java 抽象工厂 类图_spring学习中常用到的工厂,抽象工厂学习 | 学步园
工廠模式有簡(jiǎn)單工廠模式,工廠方法模式和抽象工廠模式幾種形態(tài)。其中簡(jiǎn)單工廠模式和工廠方法模式已經(jīng)在前面作過(guò)介紹。在這里,我們來(lái)介紹抽象工廠模式。
抽象工廠模式是所有形態(tài)的工廠模式中最為抽象和最具廣泛性的一種形態(tài)。
抽象工廠模式的定義
抽象工廠模式是工廠方法模式的進(jìn)一步擴(kuò)廣化和抽象化。我們給出抽象工廠模式的類圖定義如下。
圖1. 抽象工廠模式的類圖定義
從上圖可以看出,簡(jiǎn)單工廠模式涉及到以下的角色
抽象工廠(AbstractFactory)類或接口
擔(dān)任這個(gè)角色的是工廠方法模式的核心,它是與應(yīng)用程序無(wú)關(guān)的。任何在模式中創(chuàng)立對(duì)象的工廠類必須實(shí)現(xiàn)這個(gè)接口,或繼承這個(gè)類。
實(shí)工廠類 (Conrete Factory)
擔(dān)任這個(gè)角色的是與應(yīng)用程序緊密相關(guān)的,直接在應(yīng)用程序調(diào)用下,創(chuàng)立產(chǎn)品實(shí)例的那樣一些類。
抽象產(chǎn)品 (Abstract Product)
擔(dān)任這個(gè)角色的類是工廠方法模式所創(chuàng)立的對(duì)象的父類,或它們共同擁有的接口。
實(shí)產(chǎn)品 (Concrete Product)
擔(dān)任這個(gè)角色的類是工廠方法模式所創(chuàng)立的任何對(duì)象所屬的類。
怎么這個(gè)類圖和工廠方法模式的類圖看起來(lái)是一樣的?
是的,圖是一樣的,但是含義有很大的不同。必須指出,在抽象工廠模式中,抽象產(chǎn)品 (AbstractProduct) 可能是一個(gè)或多個(gè),從而構(gòu)成一個(gè)或多個(gè)產(chǎn)品族(Product Family)。 在只有一個(gè)產(chǎn)品族的情況下,抽象工廠模式實(shí)際上退化到工廠方法模式。在上面的類圖中,只給出了一個(gè)產(chǎn)品族,相當(dāng)于位圖中的一個(gè)點(diǎn),而完整的位圖應(yīng)當(dāng)是三維的,如下圖。
圖2. 抽象工廠模式的位圖
從位圖可以清楚地看到,與紙面垂直的數(shù)軸,即第三維軸,是代表產(chǎn)品族的數(shù)軸。上面的位圖中展示的是有兩個(gè)產(chǎn)品族,族A和族B的情形。
在只有一個(gè)產(chǎn)品族時(shí),第三維就坍縮掉,位圖也就只剩下兩維。這時(shí)抽象工廠模式就退化得與工廠方法模式一模一樣。
在什么情形下應(yīng)當(dāng)使用抽象工廠模式
在以下情況下,應(yīng)當(dāng)考慮使用抽象工廠模式。
首先,一個(gè)系統(tǒng)應(yīng)當(dāng)不依賴于產(chǎn)品類實(shí)例被創(chuàng)立,組成,和表示的細(xì)節(jié)。這對(duì)于所有形態(tài)的工廠模式都是重要的。
其次,這個(gè)系統(tǒng)的產(chǎn)品有多于一個(gè)的產(chǎn)品族。
第三,同屬于同一個(gè)產(chǎn)品族的產(chǎn)品是設(shè)計(jì)成在一起使用的。這一約束必須得在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來(lái)。
最后,不同的產(chǎn)品以一系列的接口的面貌出現(xiàn),從而使系統(tǒng)不依賴于接口實(shí)現(xiàn)的細(xì)節(jié)。
其中第二丶第三個(gè)條件是我們選用抽象工廠模式而非其它形態(tài)的工廠模式的關(guān)鍵性條件。
抽象工廠模式在小花果園系統(tǒng)中的實(shí)現(xiàn)
現(xiàn)在,我們?cè)诜鹆_里達(dá)的渡假小屋修整好啦。接下來(lái),一項(xiàng)重要而光榮的工作,就是開發(fā)小屋后面的小花園。這意味著,我們有兩處小花園需要照料,一處在北方地區(qū),另一處在亞熱帶地區(qū)。抽象工廠模式正好適用于我們的情況。
圖3. 抽象工廠模式應(yīng)用于小花果園系統(tǒng)中。三種不同的背景顏色可以區(qū)分工廠類,蔬菜類(第一產(chǎn)品族),和水果類的類圖(第二產(chǎn)品族)
兩處花園就相當(dāng)于兩個(gè)產(chǎn)品族。顯然,給北方花園的植物是要種植在一起的,給南方花園的植物是要另種植在一起的。這種分別應(yīng)當(dāng)體現(xiàn)在系統(tǒng)的設(shè)計(jì)上面。這就滿足了應(yīng)當(dāng)使用抽象工廠模式的第二和第三個(gè)條件。
相關(guān)代碼如下:
創(chuàng)建JAVA工程
新建三個(gè)包:
分別為:factory.impl? 存放接口
factory.action? 存放類
factory.test??? 測(cè)試類
源代碼如下:可運(yùn)行:
1. FruitIF 接口
package factory.impl;
/**
* 類說(shuō)明???? 水果接口
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:09:11
*/
public interface FruitIF {
public String getName();
}
2.Gardener 接口
package factory.impl;
/**
* 類說(shuō)明????? 園藝愛好者接口類
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午01:57:59
*/
public interface Gardener {
// 返回蔬菜類接口
public VeggieIF createVeggie(String name);
// 返回水果類接口
public FruitIF createFruit(String name) ;
}
3.FruitIF? 接口
package factory.impl;
/**
* 類說(shuō)明???? 水果接口
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:09:11
*/
public interface FruitIF {
public String getName();
}
package factory.action;
import factory.impl.FruitIF;
/**
* 類說(shuō)明???? 南方水果實(shí)現(xiàn)類
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:14:09
*/
public class NorthernFruit implements FruitIF {
public String name;
public NorthernFruit(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package factory.action;
import factory.impl.FruitIF;
import factory.impl.Gardener;
import factory.impl.VeggieIF;
/**
* 類說(shuō)明 南方園藝受好者
*
* @author zhaoguoli
* @version v1.0 創(chuàng)建時(shí)間:2009-4-10 下午01:59:25
*/
public class NorthernGardener implements Gardener {
// 返回蔬菜類接口
public VeggieIF createVeggie(String name) {
return new NorthernVeggie(name);
}
// 返回水果類接口
public FruitIF createFruit(String name) {
return new NorthernFruit(name);
}
}
package factory.action;
import factory.impl.VeggieIF;
/**
* 類說(shuō)明???? 南方菜實(shí)現(xiàn)類
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:11:58
*/
public class NorthernVeggie implements VeggieIF {
private String name;
public NorthernVeggie(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package factory.action;
import factory.impl.FruitIF;
/**
* 類說(shuō)明???? 北方水果實(shí)現(xiàn)類
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:20:57
*/
public class SouthernFruit implements FruitIF {
public String name;
public SouthernFruit(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package factory.action;
import factory.impl.FruitIF;
import factory.impl.Gardener;
import factory.impl.VeggieIF;
/**
* 類說(shuō)明
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:23:52
*/
public class SouthernGardener implements Gardener {
// 返回蔬菜類接口
public VeggieIF createVeggie(String name) {
return new SouthernVeggie(name);
}
// 返回水果類接口
public FruitIF createFruit(String name) {
return new SouthernFruit(name);
}
}
package factory.action;
import factory.impl.VeggieIF;
/**
* 類說(shuō)明???? 北方菜實(shí)現(xiàn)類
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:22:02
*/
public class SouthernVeggie implements VeggieIF {
public String name;
public SouthernVeggie(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package factory.test;
import factory.action.NorthernGardener;
import factory.action.SouthernGardener;
import factory.impl.Gardener;
/**
* 類說(shuō)明???? 測(cè)試抽象工廠模式
* @author?? zhaoguoli
* @version? v1.0? 創(chuàng)建時(shí)間:2009-4-10 下午02:26:18
*/
public class FactoryTest {
/**
* 方法說(shuō)明:
* @param args
*/
public static void main(String[] args) {
// TODO 自動(dòng)生成方法存根
// 南方園藝者生產(chǎn)花和菜
String name = null;
// 南方園藝者生產(chǎn)花和菜
NorthernGardener northernGardener = new NorthernGardener();
Gardener gardener = (Gardener)northernGardener;
name = "香蕉";
System.out.println(northernGardener.createFruit(name).getName());
name = "南菜";
System.out.println(northernGardener.createVeggie(name).getName());
// 北方園藝者生產(chǎn)花和菜
SouthernGardener southernGardener = new SouthernGardener();
name = "蘋果";
System.out.println(southernGardener.createFruit(name).getName());
name = "北菜";
System.out.println(southernGardener.createVeggie(name).getName());
}
}
運(yùn)行結(jié)果如下:
香蕉
南菜
蘋果
北菜
spring使用時(shí),會(huì)將園藝者接口中也定義方法,一切盡量用接口。
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的java 抽象工厂 类图_spring学习中常用到的工厂,抽象工厂学习 | 学步园的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c#(服务器)与java(客户端)通过s
- 下一篇: java并发编程实践 读书笔记_Java