摘要:在之前內(nèi)容里,介紹了工廠模式中的簡(jiǎn)單工廠和工廠方法內(nèi)容,這我們繼續(xù)工廠模式的學(xué)習(xí),今天學(xué)習(xí)抽象工廠模式。這樣的工廠形式就是抽象工廠模式抽象工廠模式提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴(lài)對(duì)象,而不需要明確指定具體類(lèi)。
在之前內(nèi)容里,介紹了工廠模式中的簡(jiǎn)單工廠和工廠方法內(nèi)容,這我們繼續(xù)工廠模式的學(xué)習(xí),今天學(xué)習(xí)抽象工廠模式。
當(dāng)直接實(shí)例化一個(gè)對(duì)象時(shí),就是在依賴(lài)它的具體類(lèi)??匆粡垖?duì)象依賴(lài)圖
很明顯PizzaStore依賴(lài)所有披薩對(duì)象,所有的具體pizza都從PizzaStore當(dāng)中產(chǎn)生。
當(dāng)下面各個(gè)新增一種披薩種類(lèi),就相當(dāng)于多了一個(gè)依賴(lài),上面PizzaStore可能就要修改。
這里引出一個(gè)原則:依賴(lài)倒置原則。
注:要依賴(lài)抽象,不要依賴(lài)具體類(lèi)。感覺(jué)有點(diǎn)像面向接口編程,而不面向?qū)崿F(xiàn)編程。確實(shí)這很相似,然而這里更強(qiáng)調(diào)“抽象”.這個(gè)原則說(shuō)明:不能讓“高層組件”依賴(lài)“底層組件”,換句話說(shuō)好比人要吃雞鴨魚(yú)肉等食物攝取營(yíng)養(yǎng),但是人不吃雞鴨魚(yú)肉也能從別的許多食物的攝取營(yíng)養(yǎng)物質(zhì)的把。所以二者不應(yīng)該是依賴(lài)的關(guān)系,回過(guò)來(lái)說(shuō),“高層組件”和“底層組件”都要依賴(lài)抽象。
PizzaStore是“高層組件”,而各個(gè)披薩具體實(shí)現(xiàn)PizzaStore的具體實(shí)現(xiàn)類(lèi),就為“底層組件”,很明白,PizzaStore依賴(lài)這些具體比薩類(lèi)。
我們把依賴(lài)倒置原則,放在我們目前的披薩店項(xiàng)目中。類(lèi)圖如下
想要遵循依賴(lài)倒置原則,(依賴(lài)抽象)工廠方式并不一定是最好的方法,但卻是最有效方法之一。
何為“倒置”?
前面說(shuō)“依賴(lài)”,現(xiàn)在來(lái)解釋解釋倒置原則,在上面當(dāng)中我們看到各個(gè)pizza具體類(lèi)(低層組件)向上指向了Pizza(高層組件),底層組件現(xiàn)在竟然依賴(lài)高層組件,對(duì)比圖一當(dāng)中對(duì)象(向下指向)依賴(lài)具體實(shí)現(xiàn)類(lèi)情況,是不是指向都反過(guò)來(lái)了。所以說(shuō)倒置指的就是和一般OO設(shè)計(jì)的思考方式完全相反。而現(xiàn)在我們的設(shè)計(jì)就讓高層和底層組件都依賴(lài)Pizza這個(gè)抽象。
所以說(shuō)若要遵循依賴(lài)倒置原則的話必須遵守下面幾點(diǎn)要求。
1:變量不可以持有具體類(lèi)的引用。
注:如果使用new,就會(huì)持有具體類(lèi)的引用。你可以使用工廠模式避免這個(gè)問(wèn)題。
2:不要讓類(lèi)派生自具體類(lèi)。
注:如果派生自具體類(lèi),就會(huì)依賴(lài)這個(gè)具體類(lèi)。請(qǐng)派生自一個(gè)抽象
3:不要覆蓋基類(lèi)中已經(jīng)實(shí)現(xiàn)的方法。
編者注:包括我之前做的幾期模式文章,當(dāng)學(xué)習(xí)到工廠模式的時(shí)候我也有腦漿糊時(shí)候,倘若真的寫(xiě)項(xiàng)目程序之前都要想如何使用什么設(shè)計(jì)模式的話,恐怕我什么程序都寫(xiě)不出來(lái),在設(shè)計(jì)模式中,無(wú)論有多少原則,其實(shí)是要盡量去達(dá)到,而不是說(shuō)隨時(shí)都要遵守原則或模式。其實(shí)很多時(shí)候任何Java程序在某種程度上來(lái)說(shuō)都做不到百分之百遵守原則,都有違反方針地方,但設(shè)計(jì)模式可以作為一個(gè)項(xiàng)目的靈魂。
但是,如果你深入體驗(yàn)?zāi)J剑瑢⑦@些模式內(nèi)化成你思考的一部分,那么在設(shè)計(jì)時(shí),你將知道何時(shí)有足夠的理由違反這些原則。就比方說(shuō)當(dāng)你實(shí)例化一個(gè)字符串的時(shí)候,你是不是直接實(shí)例化了?其實(shí)我們平時(shí)在程序中也都不假思索的實(shí)例化字符串對(duì)象嗎?有違反這個(gè)原則嗎?有!能這樣做嗎?能!為什么?因?yàn)樽址荒芨淖儭0ㄎ易约耗壳皩W(xué)習(xí)設(shè)計(jì)模式都還只是學(xué)“形”,我離設(shè)計(jì)模式的“心”還有不少的距離。
回到我們披薩店,現(xiàn)在看看我們披薩店“生意”是蒸蒸日上,具體彈性的框架,維護(hù)拓展起來(lái)也比最初設(shè)計(jì)的強(qiáng)很多,雖然花的功夫不少,但往往是值得的。
某一天你接到了好幾個(gè)顧客的投訴電話,投訴的內(nèi)容大體相同,某某加盟店里的食材不新鮮,甚至有媒體曝光你的某些加盟店為了降低成本,使用劣質(zhì)原料。身為老板得你,必須采取一些辦法,阻止這樣的情況再次發(fā)生。
往后幾天,你親自考察了位于紐約和芝加哥的兩家加盟店,經(jīng)過(guò)研究決定為確保加盟店使用高質(zhì)量的原料,你打算建造一家生產(chǎn)原料的工廠,并將原料運(yùn)到各個(gè)加盟店專(zhuān)供,下面是你寫(xiě)的兩份菜單
現(xiàn)在我們建造一個(gè)工廠,來(lái)生產(chǎn)原料,
定義工廠接口,負(fù)責(zé)創(chuàng)建原料
這里有很多新類(lèi),每個(gè)原料都是一個(gè)類(lèi)(接口),每個(gè)原料都有個(gè)create方法,到時(shí)候我們都要具體展開(kāi)。
下面具體創(chuàng)建紐約原料工廠,
每個(gè)原料都重載接口,根據(jù)不同風(fēng)味定制添加不同的調(diào)料,對(duì)于蔬菜(Veggies),用一個(gè)數(shù)組做返回值,這里我就自己寫(xiě)死了數(shù)組,芝加哥工廠暫時(shí)不放出。
這里Pizza就需要修改了,好讓它能使用工廠生產(chǎn)出來(lái)的原料。
下面是創(chuàng)建披薩,下面以芝士披薩為例,不在像之前那樣做法了,寫(xiě)出區(qū)域性話,就單單創(chuàng)建某某味道的披薩
下面圖將給你更好的說(shuō)明(我就直接引用書(shū)中筆記了)
下面是修改加盟店代碼以紐約店為例,紐約店會(huì)用到紐約披薩原料工廠,把工廠對(duì)象傳入每個(gè)披薩里就能“獲取”對(duì)應(yīng)原料。
相比于之前的createPizza方法,這個(gè)版本兩者之間有何異同呢?
我們目前做了這些。
這樣的工廠形式就是抽象工廠模式
抽象工廠模式:提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴(lài)對(duì)象,而不需要明確指定具體類(lèi)。
下面是抽象工廠類(lèi)圖
抽象方法,給我感覺(jué)是它更多運(yùn)用抽象形式,簡(jiǎn)化編碼當(dāng)中復(fù)雜性。
下面是工廠方法和抽象工廠兩種模式的對(duì)比
工廠方法:
抽象工廠:
其實(shí),無(wú)論簡(jiǎn)單工廠,工廠方法還是抽象工廠方法,都對(duì)我們提升代碼質(zhì)量有很大幫助。
要點(diǎn):
1:所有的工廠都是用來(lái)封裝對(duì)象的創(chuàng)建
2:簡(jiǎn)單工廠,雖然不算是設(shè)計(jì)模式,但卻是一個(gè)很好的編碼習(xí)慣,可以使客戶(hù)和具體類(lèi)解耦
3:工廠方法使用繼承:把對(duì)象的創(chuàng)建放在子類(lèi),子類(lèi)實(shí)現(xiàn)工廠方法。
4:抽象工廠模式使用對(duì)象組合:對(duì)象的創(chuàng)建被是現(xiàn)在工廠的接口中。
5:所有的工廠模式都是減少程序中類(lèi)之間依賴(lài),松耦合。
6:第一次了解原來(lái)實(shí)例化可以延遲到子類(lèi)中進(jìn)行。
7:學(xué)習(xí)了依賴(lài)倒置原則。
8:面向抽象編程,不面向具體類(lèi)編輯,盡管自己還是會(huì)犯老毛病。
下面放出實(shí)例的全部源碼,由于源碼類(lèi)文件較多,先放出了項(xiàng)目class圖
Material_Implements包下內(nèi)容
披薩工廠接口
package Factory_Interface; import Material_Interface.Cheese; import Material_Interface.Clams; import Material_Interface.Dough; import Material_Interface.Pepperoni; import Material_Interface.Sauce; import Material_Interface.Veggies; /** * 這時(shí)我們需要給披薩店送原料了 建立一家生產(chǎn)原料的工廠 添加各種原料 * * @author Joy * */ public interface PizzaIngredientFactory { // 面餅 public Dough createDough(); // 醬料 public Sauce createSauce(); // 芝士奶酪 public Cheese createCheese(); // 各種蔬菜,數(shù)組 public Veggies[] createVeggies(); // 香腸 public Pepperoni createPepperoni(); // 海鮮 public Clams createClam(); }
兩個(gè)具體工廠實(shí)現(xiàn)
package Factory_Implements; import Factory_Interface.PizzaIngredientFactory; import Material_Implements.FreshClams; import Material_Implements.Garlic; import Material_Implements.MarinaraSauce; import Material_Implements.Mushroom; import Material_Implements.Onion; import Material_Implements.RedPepper; import Material_Implements.ReggianoCheese; import Material_Implements.SlicedPepperoni; import Material_Implements.ThinCrustDough; import Material_Interface.Cheese; import Material_Interface.Clams; import Material_Interface.Dough; import Material_Interface.Pepperoni; import Material_Interface.Sauce; import Material_Interface.Veggies; /** * 紐約披薩店原料工廠實(shí)現(xiàn),工廠專(zhuān)精大蒜番茄醬料,干酪,鮮蛤蠣 * * @author Joy * */ // 具體的原料工廠都要實(shí)現(xiàn)PizzaIngredientFactory類(lèi) public class NYPizzaIngredientFactory implements PizzaIngredientFactory { @Override public Dough createDough() { return new ThinCrustDough(); } @Override public Sauce createSauce() { return new MarinaraSauce(); } @Override public Cheese createCheese() { return new ReggianoCheese(); } @Override public Veggies[] createVeggies() { Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() }; return veggies; } @Override public Pepperoni createPepperoni() { return new SlicedPepperoni(); } @Override public Clams createClam() { return new FreshClams(); } }
package Factory_Implements; import Factory_Interface.PizzaIngredientFactory; import Material_Implements.BlackOlives; import Material_Implements.Eggplant; import Material_Implements.FrozenClams; import Material_Implements.MozzarellaCheese; import Material_Implements.PlumTomatoSauce; import Material_Implements.SlicedPepperoni; import Material_Implements.Spinach; import Material_Implements.ThickCrustDough; import Material_Interface.Cheese; import Material_Interface.Clams; import Material_Interface.Dough; import Material_Interface.Pepperoni; import Material_Interface.Sauce; import Material_Interface.Veggies; /** * 加州披薩店原料工廠 * * @author Joy * */ public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { @Override public Dough createDough() { return new ThickCrustDough(); } @Override public Sauce createSauce() { return new PlumTomatoSauce(); } @Override public Cheese createCheese() { return new MozzarellaCheese(); } @Override public Veggies[] createVeggies() { Veggies veggies[] = { new BlackOlives(), new Spinach(), new Eggplant() }; return veggies; } @Override public Pepperoni createPepperoni() { return new SlicedPepperoni(); } @Override public Clams createClam() { return new FrozenClams(); } }
各個(gè)原料接口
package Material_Interface; /** * 芝士奶酪類(lèi) * @author Joy * */ public interface Cheese { //只需定義接口,具體實(shí)現(xiàn)讓實(shí)現(xiàn)類(lèi)搞定 public String toString(); }
package Material_Interface; /** * 海蠣類(lèi) * @author Joy * */ public interface Clams { public String toString(); }
package Material_Interface; /** * 面餅類(lèi) * @author Joy * */ public interface Dough { public String toString(); }
package Material_Interface; /** * 香腸類(lèi) * @author Joy * */ public interface Pepperoni { public String toString(); }
package Material_Interface; /** * 醬料類(lèi) * @author Joy * */ public interface Sauce { public String toString(); }
package Material_Interface; /** * 蔬菜類(lèi) * @author Joy * */ public interface Veggies { public String toString(); }
下面就是各個(gè)原料的具體實(shí)現(xiàn)
package Material_Implements; import Material_Interface.Veggies; public class BlackOlives implements Veggies { public String toString() { return "黑橄欖"; } }
package Material_Implements; import Material_Interface.Veggies; public class Eggplant implements Veggies { public String toString() { return "茄子"; } }
package Material_Implements; import Material_Interface.Clams; public class FreshClams implements Clams { public String toString() { return "鮮海蠣"; } }
package Material_Implements; import Material_Interface.Clams; public class FrozenClams implements Clams { public String toString() { return "海灣的鮮海蠣"; } }
package Material_Implements; import Material_Interface.Veggies; public class Garlic implements Veggies { public String toString() { return "大蒜"; } }
package Material_Implements; import Material_Interface.Sauce; public class MarinaraSauce implements Sauce { @Override public String toString() { return "番茄醬"; } }
package Material_Implements; import Material_Interface.Cheese; public class MozzarellaCheese implements Cheese { @Override public String toString() { return "碎芝士"; } }
package Material_Implements; import Material_Interface.Veggies; public class Mushroom implements Veggies { public String toString() { return "香菇"; } }
package Material_Implements; import Material_Interface.Veggies; public class Onion implements Veggies { public String toString() { return "洋蔥"; } }
package Material_Implements; import Material_Interface.Sauce; public class PlumTomatoSauce implements Sauce { public String toString() { return "梅子番茄醬"; } }
package Material_Implements; import Material_Interface.Veggies; public class RedPepper implements Veggies { public String toString() { return "紅辣椒"; } }
package Material_Implements; import Material_Interface.Cheese; public class ReggianoCheese implements Cheese { public String toString() { return "干奶酪"; } }
package Material_Implements; import Material_Interface.Pepperoni; public class SlicedPepperoni implements Pepperoni { public String toString() { return "香腸切片"; } }
package Material_Implements; import Material_Interface.Veggies; public class Spinach implements Veggies { public String toString() { return "菠菜"; } }
package Material_Implements; import Material_Interface.Dough; public class ThickCrustDough implements Dough { public String toString() { return "厚面餅"; } }
package Material_Implements; import Material_Interface.Dough; public class ThinCrustDough implements Dough { public String toString() { return "薄面餅"; } }
下面是Pizza“工廠”(抽象)方法
package Pizza; import Material_Interface.Cheese; import Material_Interface.Clams; import Material_Interface.Dough; import Material_Interface.Pepperoni; import Material_Interface.Sauce; import Material_Interface.Veggies; public abstract class Pizza { String name;// 披薩名稱(chēng) Dough dough;// 面團(tuán)類(lèi)型 Sauce sauce;// 醬料 // ArrayList toppings = new ArrayList();// 一套佐料(下面原料代替了list) // 每個(gè)披薩都持有一組需用到的原料 Veggies veggies[]; Cheese cheese; Pepperoni pepperoni; Clams clams; public void setName(String name) { this.name = name; } public String getName() { return name; } /** * //把prepare方法抽象化,獲取來(lái)自原料工廠的原料 Pizza類(lèi)完全不關(guān)心具體原料是什么,只知道如何制作披薩, * 比薩和原料之間被解耦,往后拓展不同口味披薩,建立不同的披薩工廠也很方便 Pizza類(lèi)被復(fù)用 */ // 準(zhǔn)備 public abstract void prepare(); // 烘烤 public void bake() { System.out.println(" " + "披薩正在烘烤,需烘烤25分鐘。。。"); } // 切片 public void cut() { System.out.println("制作完成,給披薩切片。。。"); } // 裝盒 public void box() { System.out.println("給披薩打包裝盒。。。"); } // 輸出客人點(diǎn)的披薩信息 @Override public String toString() { StringBuffer display = new StringBuffer(); display.append(name + " "); if (dough != null) { display.append(dough + " "); } if (sauce != null) { display.append(sauce + " "); } if (cheese != null) { display.append(cheese + " "); } if (veggies != null) { for (int i = 0; i < veggies.length; i++) { display.append(veggies[i] + ", "); } } if (pepperoni != null) { display.append(pepperoni + " "); } if (clams != null) { display.append(clams + " "); } return display.toString(); } }
下面是具體Pizza實(shí)現(xiàn)
package Pizza; import Factory_Interface.PizzaIngredientFactory; //芝士披薩 public class CheesePizza extends Pizza { PizzaIngredientFactory ingredientFactory; // 要制作披薩,要先從對(duì)于工廠獲取原料,所以構(gòu)造器初始化數(shù)據(jù) public CheesePizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } // 這里就不在以前Pizza類(lèi)直接寫(xiě)死,而是更加靈活使用 // prepare()方法一步步創(chuàng)建芝士披薩,需要的原料全部從“工廠”中獲取 @Override public void prepare() { System.out.println("準(zhǔn)備 " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); } }
package Pizza; import Factory_Interface.PizzaIngredientFactory; //海蠣披薩 public class ClamPizza extends Pizza { PizzaIngredientFactory ingredientFactory; public ClamPizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } public void prepare() { System.out.println("準(zhǔn)備 " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); clams = ingredientFactory.createClam(); } }
package Pizza; import Factory_Interface.PizzaIngredientFactory; //香腸披薩 public class PepperoniPizza extends Pizza { PizzaIngredientFactory ingredientFactory; public PepperoniPizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } public void prepare() { System.out.println("準(zhǔn)備 " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); veggies = ingredientFactory.createVeggies(); pepperoni = ingredientFactory.createPepperoni(); } }
package Pizza; import Factory_Interface.PizzaIngredientFactory; //素食披薩 public class VeggiePizza extends Pizza { PizzaIngredientFactory ingredientFactory; public VeggiePizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } public void prepare() { System.out.println("準(zhǔn)備 " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); veggies = ingredientFactory.createVeggies(); } }
下面是PizzaStore接口
package Store; import Pizza.Pizza; /** * PizzaStore相當(dāng)于客戶(hù), 往后會(huì)有很多類(lèi)似此類(lèi)進(jìn)行拓展 * * 在這里orderPizza()方法對(duì)pizz對(duì)象做了很多事(createPizza,prepare,bake,cut,box) * 但是由于Pizza對(duì)象是抽象的(接口), * orderPizza()并不知道具體哪些實(shí)際類(lèi)參與進(jìn)來(lái)了(相當(dāng)于實(shí)現(xiàn)Pizza接口的實(shí)現(xiàn)類(lèi)有哪些orderPizza()方法并不知道) * 換句話說(shuō),這就是解耦,減少相互依賴(lài) * * 同理createPizza()方法中也不知道創(chuàng)建的具體是什么披薩 只知道披薩可以被準(zhǔn)備,被烘烤,被切片,被裝盒行為而已 * */ // 披薩店 public abstract class PizzaStore { // 點(diǎn)單 public Pizza orderPizza(String type) { // createPizza()方法從工廠對(duì)象中取出, // 并且方法也不再這里實(shí)現(xiàn),定義為抽象類(lèi),誰(shuí)需要在拿走方法去具體實(shí)現(xiàn) Pizza pizza = createPizza(type); System.out.print("----制作一個(gè)" + pizza); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } // 把工廠對(duì)象移到這個(gè)方法里,并封裝 // 現(xiàn)在工廠方法為抽象的,子類(lèi)必須實(shí)現(xiàn)這個(gè)抽象方法 public abstract Pizza createPizza(String item); }
下面是兩個(gè)加盟店的具體實(shí)現(xiàn)
package Store; import Factory_Implements.NYPizzaIngredientFactory; import Factory_Interface.PizzaIngredientFactory; import Pizza.CheesePizza; import Pizza.ClamPizza; import Pizza.PepperoniPizza; import Pizza.Pizza; import Pizza.VeggiePizza; /** * 此時(shí)NYStylePizzaStore所封裝的知識(shí)是關(guān)于如何制作紐約風(fēng)格的比薩 * * @author Joy * */ // 紐約風(fēng)格披薩店(分店) public class NYStylePizzaStore extends PizzaStore { /** * 相比之前寫(xiě)的這里添加了工廠類(lèi) */ // 根據(jù)披薩的不同,創(chuàng)建不同披薩(具體實(shí)現(xiàn)類(lèi)) @Override public Pizza createPizza(String item) { Pizza pizza = null; // 這里多態(tài)創(chuàng)建紐約原料工廠,該工廠負(fù)責(zé)紐約風(fēng)味的披薩 PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory(); if (item.equals("芝士")) { // 實(shí)例化具體披薩類(lèi)型,并傳進(jìn)該比薩所需要的工廠,以便取得原料 pizza = new CheesePizza(ingredientFactory); pizza.setName("紐約芝士披薩"); } else if (item.equals("素食")) { pizza = new VeggiePizza(ingredientFactory); pizza.setName("紐約素食披薩"); } else if (item.equals("海蠣")) { pizza = new ClamPizza(ingredientFactory); pizza.setName("紐約海蠣披薩"); } else if (item.equals("香腸")) { pizza = new PepperoniPizza(ingredientFactory); pizza.setName("紐約香腸披薩"); } return pizza; } }
package Store; import Factory_Implements.ChicagoPizzaIngredientFactory; import Factory_Interface.PizzaIngredientFactory; import Pizza.CheesePizza; import Pizza.ClamPizza; import Pizza.PepperoniPizza; import Pizza.Pizza; import Pizza.VeggiePizza; /** * 此時(shí)ChicagoStylePizzaStore所封裝的知識(shí)是關(guān)于如何制作芝加哥風(fēng)格的比薩 * * @author Joy * */ // 芝加哥披薩店(分店) public class ChicagoStylePizzaStore extends PizzaStore { Pizza pizza = null; // 這里多態(tài)創(chuàng)建紐約原料工廠,該工廠負(fù)責(zé)紐約風(fēng)味的披薩 PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory(); @Override public Pizza createPizza(String item) { if (item.equals("芝士")) { pizza = new CheesePizza(ingredientFactory); pizza.setName("芝加哥芝士披薩"); } else if (item.equals("素食")) { pizza = new VeggiePizza(ingredientFactory); pizza.setName("芝加哥素食披薩"); } else if (item.equals("海鮮")) { pizza = new ClamPizza(ingredientFactory); pizza.setName("芝加哥海蠣披薩"); } else if (item.equals("香腸")) { pizza = new PepperoniPizza(ingredientFactory); pizza.setName("芝加哥香腸披薩"); } return pizza; } }
測(cè)試類(lèi)
package TestMain; import Pizza.Pizza; import Store.ChicagoStylePizzaStore; import Store.NYStylePizzaStore; import Store.PizzaStore; public class TestMain { public static void main(String[] args) { PizzaStore nyStore = new NYStylePizzaStore(); PizzaStore chicagoStore = new ChicagoStylePizzaStore(); System.out.println("===================================="); Pizza pizza3 = nyStore.orderPizza("香腸"); System.out.println("Joy點(diǎn)了一個(gè)" + pizza3); System.out.println("===================================="); Pizza pizza4=chicagoStore.orderPizza("海鮮"); System.out.println("Joy點(diǎn)了一個(gè)" + pizza4); } }
效果圖:
工廠模式給我最大感受就是對(duì)編寫(xiě)好的代碼的理解程度加深,想法也更加考慮拓展了,當(dāng)然還需反復(fù)多練習(xí),模擬代碼已經(jīng)全部放出,注釋也寫(xiě)的比較清楚,若有不理解歡迎留言
感謝你看到這里,至此工廠模式內(nèi)容結(jié)束,本人文筆隨便,若有不足或錯(cuò)誤之處望給予指點(diǎn),90度彎腰~~~很快我會(huì)發(fā)布下一個(gè)設(shè)計(jì)模式內(nèi)容,生命不息,編程不止!
參考書(shū)籍:《Head First 設(shè)計(jì)模式》
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70195.html
摘要:對(duì)象字面量創(chuàng)建對(duì)象張三學(xué)生這種方式的好處顯而易見(jiàn),就是解決了之前的缺點(diǎn)。構(gòu)造函數(shù)模式張三學(xué)生李四學(xué)生與之前工廠模式的方法對(duì)比變量名首字母大寫(xiě)了在函數(shù)內(nèi)沒(méi)有顯式的創(chuàng)建及返回對(duì)象而使用了創(chuàng)建時(shí)使用了關(guān)鍵字。 面向?qū)ο笫荍S的重點(diǎn)與難點(diǎn),但也是走向掌握J(rèn)S的必經(jīng)之路,有很多的文章或書(shū)籍中都對(duì)其進(jìn)行了詳細(xì)的描述,本沒(méi)有必要再寫(xiě)這些,但是對(duì)于學(xué)習(xí)來(lái)說(shuō),講給別人聽(tīng)對(duì)自己來(lái)說(shuō)是一種更好的受益方式。我...
摘要:對(duì)象字面量創(chuàng)建對(duì)象張三學(xué)生這種方式的好處顯而易見(jiàn),就是解決了之前的缺點(diǎn)。構(gòu)造函數(shù)模式張三學(xué)生李四學(xué)生與之前工廠模式的方法對(duì)比變量名首字母大寫(xiě)了在函數(shù)內(nèi)沒(méi)有顯式的創(chuàng)建及返回對(duì)象而使用了創(chuàng)建時(shí)使用了關(guān)鍵字。 面向?qū)ο笫荍S的重點(diǎn)與難點(diǎn),但也是走向掌握J(rèn)S的必經(jīng)之路,有很多的文章或書(shū)籍中都對(duì)其進(jìn)行了詳細(xì)的描述,本沒(méi)有必要再寫(xiě)這些,但是對(duì)于學(xué)習(xí)來(lái)說(shuō),講給別人聽(tīng)對(duì)自己來(lái)說(shuō)是一種更好的受益方式。我...
摘要:設(shè)計(jì)模式的定義在面向?qū)ο筌浖O(shè)計(jì)過(guò)程中針對(duì)特定問(wèn)題的簡(jiǎn)潔而優(yōu)雅的解決方案。從前由于使用的局限性,和做的應(yīng)用相對(duì)簡(jiǎn)單,不被重視,就更談不上設(shè)計(jì)模式的問(wèn)題。 ‘從大處著眼,從小處著手’,以前對(duì)這句話一知半解,自從踏出校門(mén)走入社會(huì),開(kāi)始工作以來(lái),有了越來(lái)越深的理解,偶有發(fā)現(xiàn)這句話用在程序開(kāi)發(fā)中也有用,所以,近段時(shí)間開(kāi)始嘗試著分析jQuery源碼,分析angularjs源碼,學(xué)習(xí)設(shè)計(jì)模式。 設(shè)...
摘要:結(jié)構(gòu)型模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。行為型模式模版方法模式命令模式迭代器模式觀察者模式中介者模式備忘錄模式解釋器模式模式狀態(tài)模式策略模式職責(zé)鏈模式責(zé)任鏈模式訪問(wèn)者模式。 主要版本 更新時(shí)間 備注 v1.0 2015-08-01 首次發(fā)布 v1.1 2018-03-12 增加新技術(shù)知識(shí)、完善知識(shí)體系 v2.0 2019-02-19 結(jié)構(gòu)...
閱讀 3100·2021-10-12 10:20
閱讀 2828·2021-09-27 13:56
閱讀 802·2021-09-27 13:36
閱讀 1441·2021-09-26 09:46
閱讀 2428·2019-08-30 14:02
閱讀 2696·2019-08-28 18:14
閱讀 1274·2019-08-26 10:32
閱讀 1716·2019-08-23 18:25