抽象工廠模式(Abatract Factory):????提供一個(gè)創(chuàng)建一系列相關(guān)或互相依賴對(duì)象的接口,而無(wú)需指定它們具體的類。

”AbstractProductA 和 AbatractProductB 是兩個(gè)抽象產(chǎn)品,之所以抽象,是因?yàn)樗鼈兌加锌赡苡袃煞N不同的實(shí)現(xiàn),就剛才的例子來(lái)說(shuō)就是User和Department,而ProductA、ProductA2和ProductB1、ProductB2就是對(duì)兩個(gè)抽象產(chǎn)品的具體分類的實(shí)現(xiàn),比如ProductA1可以理解為是SqlserverUser,而ProductB1是AccessUser。
? ? ”這么說(shuō),IFactory是一個(gè)抽象工廠接口,它里面應(yīng)該包含所有的產(chǎn)品創(chuàng)建的抽象方法。而ConcreteFactory和CincreteFactory2就是具體的工廠了。就像SqlserverFactory和AccessFactory一樣?!?/p>
? ? “理解的非常正確。通常是在運(yùn)行時(shí)刻再創(chuàng)建一個(gè)ConcreteFactory類的實(shí)例,這個(gè)具體的工廠再創(chuàng)建具有特定的實(shí)現(xiàn)的產(chǎn)品對(duì)象,也就是說(shuō),為創(chuàng)建不同的產(chǎn)品對(duì)象,客戶端應(yīng)使用不同的工具工廠?!?/p>
抽象工廠模式的優(yōu)點(diǎn)與缺點(diǎn)
?最大的好處便是易于交換產(chǎn)品系列,由于具體工廠類,例如 IFactory factory = new AccessFactory(),在一個(gè)應(yīng)用中只需要在初始化的時(shí)候出現(xiàn)一次,這就使得改變一個(gè)應(yīng)用的具體工廠變得非常容易,它只需要改變具體工廠即可使用不同的產(chǎn)品配置。我們的設(shè)計(jì)不能去防止需求的更改,那么我們的思想便是讓改動(dòng)變得最小,現(xiàn)在如果你要是更改數(shù)據(jù)庫(kù)訪問(wèn),我們只需要更改具體工廠模式就可以做到。第二大好處是:它讓具體的創(chuàng)建實(shí)例過(guò)程與客戶端分離,客戶端是通過(guò)它們的抽象接口操縱實(shí)例。產(chǎn)品的具體類名也是被具體工廠的實(shí)現(xiàn)分離,不會(huì)出現(xiàn)在客戶端代碼中。
缺點(diǎn):是個(gè)模式都是會(huì)有缺點(diǎn)的,都有不適用的時(shí)候,抽象模式可以很方便的切換兩個(gè)數(shù)據(jù)庫(kù)訪問(wèn)的代碼,如果根據(jù)某個(gè)特殊一點(diǎn)的需求來(lái)自增加功能,可能需要改動(dòng)的地方偏多,可以通過(guò)其他方法來(lái)改進(jìn),編程是門藝術(shù),大批量的改動(dòng)是非常丑陋的做法。
? ??????假設(shè)目前你的程序里面有兩個(gè)對(duì)象,蘋果(apple)和香蕉(banana),那么你使用工廠模式就已經(jīng)足夠了,因?yàn)樗齻儗儆谕粋€(gè)品類,都屬于水果,如果在添加一個(gè)菠蘿產(chǎn)品,也只需要把菠蘿加入到你的
水果工廠里面就夠了。
但是如果你程序里面有四個(gè)對(duì)象,蘋果汁,蘋果派,香蕉汁,香蕉派,這四個(gè)對(duì)象正好有明確的層級(jí)關(guān)系,可以抽象為兩個(gè)層級(jí),蘋果,香蕉,或者果汁,派。這時(shí)候你怎么來(lái)創(chuàng)建這些對(duì)象呢?這時(shí)候工廠模式明顯已經(jīng)不適用了,因?yàn)楣S模式是對(duì)象都實(shí)現(xiàn)了同一個(gè)接口,這時(shí)候就可以使用抽象工廠模式了。
具體怎么做呢?
就是把對(duì)象抽象一下,把這四個(gè)對(duì)象抽象為兩個(gè)接口,一個(gè)果汁接口,一個(gè)派的接口。
然后再設(shè)計(jì)一個(gè)抽象的工廠(抽象類)abstractFactory,里面生產(chǎn)抽象的對(duì)象(也就是接口)Juice,Pie,單看這個(gè)結(jié)構(gòu)就是一個(gè)工廠模式,但是我們要用生產(chǎn)的是對(duì)象而不是接口。
所以我們還需要兩個(gè)具體工廠:
一個(gè)AppleFactory繼承abstractFactory,實(shí)現(xiàn)生成Pie的方法和生成Juice的方法,實(shí)際上就是生成對(duì)象AppleJuice和ApplePie,
一個(gè)BananaFactory繼承abstractFactory,實(shí)現(xiàn)生成Pie的方法和生成Juice的方法,實(shí)際上就是生成對(duì)象BananaJuice和BananaPie,
這樣的話,對(duì)于調(diào)用者來(lái)說(shuō),我在開(kāi)發(fā)過(guò)程中,只需要知道我操作的對(duì)象是Pie或者是Juice就夠了,這樣降低了耦合。
下面看下代碼,首先是調(diào)用點(diǎn)。
package abstractFactory;
? publicclass Test {
? ? publicstaticvoid main(String args[]){
? ? ? ? AbstractFactory factory1 =newAppleFactory();? ? ? ??
????????factory1.createJuice().desc();
????????factory1.createPie().desc();
? ? ? ? //假設(shè)我們之前需要的是applePie和appleJuice對(duì)象,現(xiàn)在需要換成bananaPie和BananaJuice對(duì)象
? ? ? ? //我們只需要替換對(duì)應(yīng)的實(shí)現(xiàn)工廠(把new AppleFactory換成new BananFactory就可以了,耦合比較低)????
????????AbstractFactory factory2 =newBananaFactory();? ? ? ? ????????factory2.createJuice().desc();factory2.createPie().desc();
????????}
????????}
?下面是抽象工廠,生產(chǎn)對(duì)象的抽象。
package abstractFactory;
????????publicabstractclass AbstractFactory {
? ?????????abstract Juice createJuice();
? ????????? abstract Pie createPie();
}
下面是具體工廠兩個(gè)
package abstractFactory;
????????publicclassAppleFactoryextends AbstractFactory{
? ? @Override
? ? Juice createJuice() {
? ? ? ? returnnew AppleJuice();
? ? }
? ? @Override
? ? Pie createPie() {
? ? ? ? returnnew ApplePie();
? ? }
}
package abstractFactory;
????publicclassBananaFactoryextends? AbstractFactory{
? ? @Override
? ? Juice createJuice() {
? ? ? ? returnnew BananaJuice();
? ? }
? ? @Override
? ? Pie createPie() {
? ? ? ? returnnew BananaPie();
? ? }
}
下面是對(duì)象抽象出來(lái)的接口兩個(gè)
package abstractFactory;
????????publicinterface Juice {
? ? publicvoid desc();
}
package abstractFactory;/** * Created by songjian on 3/29/2016.
*/publicinterface? Pie {
? ? publicvoid desc();
}
最后是我們要生產(chǎn)的四個(gè)對(duì)象。
package abstractFactory;
????????publicclassAppleJuiceimplements Juice {
?????????@Override
? ? publicvoid desc() {
? ? ? ? System.out.println("蘋果汁.");
? ? }
}
package abstractFactory;
????????publicclassApplePieimplements Pie {
? ? @Override
? ? publicvoid desc() {
? ? ? ? System.out.println("蘋果派");
? ? }
}
package abstractFactory;
????publicclassBananaJuiceimplements Juice {
? ? @Override
? ? publicvoid desc() {
? ? ? ? System.out.println("香蕉汁.");
? ? }
}
package abstractFactory;
????publicclassBananaPieimplements Pie {
? ? @Override
? ? publicvoid desc() {
? ? ? ? System.out.println("香蕉派");
? ? }
}
然后最后,再配上一張,我覺(jué)得可以幫助理解的圖,沒(méi)有用UML,勉強(qiáng)算是概念圖,有點(diǎn)丑。。。
