您好,登錄后才能下訂單哦!
一、概念
提供一個創建一系列相關或相互依賴對像的接口,而無需指定它們具體的類。
二、模式動機
這一系列對像之間是相互依賴的,相當于一個產品族
三、模式的結構
通過上圖我們可以清楚的看到抽像工廠模式包括以下4個角色:
1.抽像工廠角色(AbstractFactory):抽像工廠模式的核心,與具體的商業邏輯無關,通常是一個JAVA接口或者抽像類。
2.具體工廠角色(Concrete Factory):該角色通常與具體的商業邏輯緊密相關,該角色里面的工廠方法依據具體的商業邏輯實例化具體的產品并返回,客戶端通過該角色并調用該角色的工廠方法,獲得具體產品對像,該角色通常都是一個具體JAVA類來承擔。
3.抽像產品角色:擔任這個角色的類是工廠方法模式所創建的產品的父類,或者他們共同擁有的接口,通常是一個接口或者抽像類。
4.具體產品角色:抽像工廠模式所創建的任何產品都是這個角色的實例,有一個具體JAVA類來承擔。
樣例代碼如下:
public class AbstractProductA { /** * @roseuid 59AC05990327 */ public AbstractProductA() { } } public class ProductA1 extends AbstractProductA { /** * @roseuid 59AC05990359 */ public ProductA1() { } } public class ProductA2 extends AbstractProductA { /** * @roseuid 59AC05990381 */ public ProductA2() { } } public class AbstractProductB { /** * @roseuid 59AC059903BA */ public AbstractProductB() { } } public class ProductB1 extends AbstractProductB { /** * @roseuid 59AC059A001F */ public ProductB1() { } } public class ProductB2 extends AbstractProductB { /** * @roseuid 59AC059A0049 */ public ProductB2() { } } public abstract class AbstractFactory { /** * @roseuid 59AC05690005 */ public AbstractFactory() { } /** * @return AbstractProductA * @roseuid 59ABFB0103BE */ public Abstract AbstractProductA createProductA() ; /** * @return AbstractProductB * @roseuid 59ABFB3B029D */ public Abstract AbstractProductB createProductB() ; } public class ConcreteFactory1 extends AbstractFactory { /** * @roseuid 59AC057A02FC */ public ConcreteFactory1() { } /** * @return AbstractProductA * @roseuid 59ABFB9C00C9 */ public AbstractProductA createProductA() { return new ProductA1(); } /** * @return AbstractProductB * @roseuid 59ABFBA30011 */ public AbstractProductB createProductB() { return new ProductB1(); } } public class ConcreteFactory2 extends AbstractFactory { /** * @roseuid 59AC057A02C0 */ public ConcreteFactory2() { } /** * @return AbstractProductA * @roseuid 59ABFCC701B9 */ public AbstractProductA createProductA() { return new ProductA2(); } /** * @return AbstractProductB * @roseuid 59ABFCC9001F */ public AbstractProductB createProductB() { return new ProductB2(); } }
public class Client { /** * @roseuid 59AC055700AB */ public Client() { } public static void main(String[] args){ AbstractFactory theAbstractFactory; AbstractProductA theAbstractProductA; AbstractProductB theAbstractProductB; theAbstractFactory=new ConcreteFactory1(); theAbstractProductA=theAbstractFactory.createProductA(); theAbstractProductB=theAbstractFactory.createProductB(); } }
跟據上面的模式結構圖我們對“提供一個創建一系列相關或相互依賴對像的接口,而無需指定它們具體的類” 進行一個簡要的分析:
1.相關或相互依賴對像,在這里面ProductA1的實例和ProductB1的實例就是一組相互關聯(如內在的關聯關系)或相互依賴(如整體和部分)關系,依據業務邏輯,ProductA1
只能和同一產品等級結構AbstractProductB下的ProductB1相互關聯而無法與ProductB2關聯在一起。
2.提供一個創建一系列相關或相互依賴對像的接口,而無需指定它們具體的類,這里面的接口,即為結構圖中的AbstractProductA和AbstractProductB,客戶端只依賴這些產品的接口進行編程,而不依賴于具體實現,即符合依賴倒轉原則。“無需指定它們具體的類” 即客戶端(client)跟本就不知道ProductA1、ProductA2、ProductB1和ProductB2的存在,客戶端只需要調用具體工廠的工廠方法即可返回具體的產品實例。
四、模式樣例
我們接著工廠方法模式中的樣例進行進一步分析,現在這個生產輪胎的工廠已經不滿足只生產轎車輪胎了,他現已經引入了發動機的生產線(EngineLine)、車門(DoorLine)等整個車的各種零部件生產線,可以說他現在可以輕松制造一部Car,但是也并非所有的Car都能制造,比如他現只能生產benz和BMW兩種類型的車(這樣的工廠也夠NX了),比如現在一部車只包含車輪胎、車門和發動機(當然肯定不止這么多),那么這個工廠就可以跟據客戶的要求生產BMW和benz車了,如下圖:
代碼如下:
public interface Door { public void open(); public void close(); } public class BenzDoor implements Door { @Override public void open() { System.out.println("奔馳車門開"); } @Override public void close() { System.out.println("奔馳車門關"); } } public class BmwDoor implements Door { @Override public void open() { System.out.println("寶馬車門開"); } @Override public void close() { System.out.println("寶馬車門關"); } } public interface Tire { public void getColor(); public void getLife(); public void getWidth(); } public class BenzTire implements Tire { @Override public void getColor() { System.out.println("benz車color"); } @Override public void getLife() { System.out.println("benz車life"); } @Override public void getWidth() { System.out.println("benz車width"); } } public class BmwTire implements Tire { @Override public void getColor() { System.out.println("bmw車color"); } @Override public void getLife() { System.out.println("bmw車life"); } @Override public void getWidth() { System.out.println("bmw車width"); } } public interface Engine { public void start(); public void stop(); } public class BenzEngine implements Engine { @Override public void start() { System.out.println("benz車start"); } @Override public void stop() { System.out.println("benz車stop"); } } public class BmwEngine implements Engine { @Override public void start() { System.out.println("bmw車start"); } @Override public void stop() { System.out.println("bmw車stop"); } } public interface PartFactory { public Door createDoor(); public Tire createTire(); public Engine createEngine(); } public class BenzPartFactory implements PartFactory { @Override public Door createDoor() { return new BenzDoor(); } @Override public Tire createTire() { return new BenzTire(); } @Override public Engine createEngine() { return new BenzEngine(); } } public class BmwPartFactory implements PartFactory { @Override public Door createDoor() { return new BmwDoor(); } @Override public Tire createTire() { return new BmwTire(); } @Override public Engine createEngine() { return new BmwEngine(); } } public class Car { private Door door; private Engine engine; private Tire tire; public Car(PartFactory factory) { this.door = factory.createDoor(); this.engine = factory.createEngine(); this.tire = factory.createTire(); } public Door getDoor() { return door; } public Engine getEngine() { return engine; } public Tire getTire() { return tire; } } public class Client { public static void main(String[] args) { PartFactory partFactory=new BenzPartFactory(); Car benzCar=new Car(partFactory); benzCar.getDoor().open(); benzCar.getEngine().start(); benzCar.getTire().getColor(); } }
運行結果如下:
奔馳車門開
benz車start
benz車color
跟據上面的類圖及運行結果可以做如下分析:
BenzDoor、BenzTire和BenzEngine有很強的關聯關系,我們可以說一部benz車,不可能用Bmw的車門,即BmwDoor。這種很強的關聯關系通過BenzPartFactory進行了很好的維護。對于客戶端來說,如上面的client類,如果客戶想要一部benz車,那么我只需要一個生產benz車的工廠即可,這個工廠所有的產品實例,都是benz車的部件。從運行結果我們也可以看出。
試想一下,隨著這個工廠的發展,他現在也要生產Audi的車,這時我們只要增加一個audi的車門的類AudiDoor、AudiTire 、AudiEngine和AudiPartFactory就可以了,其它的類不需要做任何的修改。但客戶說,我要在車上裝一對翅膀呢,堵車時可以飛,這時我們就要對每個工廠都要增加能返回翅膀的工廠方法,要對每個工廠進行修改,這是不符合開閉原則的。所以說抽象工廠對增加產品等級結構方面是不支持開閉原則的,對于產品族維度(如audi車)是支持開閉原則的。
五、模式的約束
對于產生一個相互關聯或依賴的產品族適用,且支持在產品族方向的擴展,不適用于產品等級方向的擴展。
六、模式的變體與擴展
1、抽像工廠提供靜態工廠方法:抽像工廠可以提供一個靜態的工廠方法,通過參數返回具體的工廠實例。
2、抽像工廠與具體工廠合并:如果在產品族方向上確定只有一個產品族,那么抽像工廠就沒有必要了,這時只需要一個具體工廠就可以了,我們可以進一步延深,為這個具體工廠提供一個靜態方法,該方法返回自已的實例。
七、與其它模式的關系
如果只有一個產品等級結構,那么就是工廠方法模式了,如下圖:
如果有多個產品等級結構,那么抽像工廠里面的每一個工廠方法都是"工廠方法"模式。
八、模式優缺點
在產口族方向支持開閉原則,在產口等級結構方向不支持開閉原則。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。