抽象工廠模式

抽象工廠模式(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)丑。。。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容