前言:按照慣例我以Head First設(shè)計(jì)模式的工廠模式例子開始編碼學(xué)習(xí)。并由簡單工廠,工廠模式,抽象工廠模式依次演變,歸納他們的相同與不同。

          話說Head First認(rèn)為簡單工廠并不是設(shè)計(jì)模式,而是一種編程習(xí)慣,但并不妨礙我們使用它,接下來我們對工廠模式一探究竟。

          1、披薩店例子

          首先我們要開一個披薩店,對于業(yè)務(wù)不復(fù)雜的情況下我們可以快速的開發(fā)出一個披薩店以及訂購披薩的邏輯
          public Pizza OrderPizza() { Pizza pizza = new Pizza(); pizza.Prepare();
          pizza.Bake(); pizza.Cut(); pizza.Box(); return pizza; } } public class Pizza {
          //準(zhǔn)備 public void Prepare() { } //烘烤 public void Bake() { } //切片 public void
          Cut() { } //裝盒 public void Box() { } }
          ? ? ?如果我們有更多的披薩種類可能需要將Pizza定義成抽象類 在訂單里面根據(jù)訂購的披薩種類返回不同的披薩,我們對披薩進(jìn)行抽象并改造Order。
          public class PizzaStore { public Pizza OrderPizza(string type) { Pizza
          pizza=null; if (type == "cheese") { pizza = new CheesePizza(); } else if (type
          == "viggie") { pizza = new VeggiePizza(); } //else if ...... pizza.Prepare();
          pizza.Bake(); pizza.Cut(); pizza.Box(); return pizza; } } public abstract class
          Pizza { //準(zhǔn)備 public void Prepare() { } //烘烤 public void Bake() { } //切片 public
          void Cut() { } //裝盒 public void Box() { } } //奶酪披薩 public class CheesePizza :
          Pizza { } //素食披薩 public class VeggiePizza : Pizza { }
          ? ?到這里我們可能想到了,如果增加披薩種類或者移除披薩那么我們將對披薩店進(jìn)行修改。

          ? ?設(shè)計(jì)原則對擴(kuò)展開放,對修改關(guān)閉。我們需要將創(chuàng)建披薩的變化封裝起來。對此弄出來一個專門創(chuàng)建披薩的“工廠“類。

          ? ?并采用靜態(tài),這樣就不需要實(shí)例化對象,也遵循了不對實(shí)現(xiàn)編程原則。
          public class PizzaStore { public Pizza OrderPizza(string type) { Pizza pizza
          = SimplePizzaFactory.CreatePizza(type); pizza.Prepare(); pizza.Bake();
          pizza.Cut(); pizza.Box(); return pizza; } } public static class
          SimplePizzaFactory { public static Pizza CreatePizza(string type) { Pizza pizza
          = null; if (type == "cheese") { pizza = new CheesePizza(); } else if (type ==
          "viggie") { pizza = new VeggiePizza(); } return pizza; } }

            這樣將創(chuàng)建披薩簡單的封裝起來即是簡單工廠(靜態(tài)工廠),簡單工廠也可以不用靜態(tài)類,但簡單工廠并不是一種專門的設(shè)計(jì)模式(有時候可能會混淆,認(rèn)為這即是”工廠模式“),更像是我們平時編程都會做的一種習(xí)慣。我們將改動封裝在一個局部當(dāng)有變化的時候只需要修改這個工廠類。

          2、更多的披薩店

          現(xiàn)在我們要開更多的披薩店,例如美國風(fēng)格披薩店(USSytlePizzaStore)、中國風(fēng)格披薩店(CHNSytlePizzaStore)。

          我們可以采用簡單工廠模式,創(chuàng)建兩個不同風(fēng)格的披薩工廠,然后創(chuàng)建兩個不同風(fēng)格的披薩店,不同風(fēng)格的披薩店使用對應(yīng)的披薩工廠來獲取。

          但是我們此時的變化點(diǎn)是披薩店。我們希望披薩店的結(jié)構(gòu)或者流程是按照一定規(guī)則的,只是不同風(fēng)格的披薩。此時我們有更好的解決辦法:工廠模式。

          接下來我們看如何實(shí)現(xiàn)
          public abstract class PizzaStore { public Pizza OrderPizza(string type) {
          Pizza pizza= CreatePizza(type); pizza.Prepare(); pizza.Bake(); pizza.Cut();
          pizza.Box(); return pizza; } public abstract Pizza CreatePizza(string type); }
          public class USSytlePizzaStore : PizzaStore { public override Pizza
          CreatePizza(string type) { Pizza pizza = null; if (type == "cheese") { pizza =
          new USStyleCheesePizza(); } else if (type == "viggie") { pizza = new
          USStyleVeggiePizza(); } return pizza; } } public class CHNSytlePizzaStore :
          PizzaStore { public override Pizza CreatePizza(string type) { Pizza pizza =
          null; if (type == "cheese") { pizza = new CHNStyleCheesePizza(); } else if
          (type == "viggie") { pizza = new CHNStyleVeggiePizza(); } return pizza; } }
          //US奶酪披薩 public class USStyleCheesePizza : Pizza { } //US素食披薩 public class
          USStyleVeggiePizza : Pizza { } //CHN奶酪披薩 public class CHNStyleCheesePizza :
          Pizza { } //CHN素食披薩 public class CHNStyleVeggiePizza : Pizza { }
          ? ?由實(shí)現(xiàn)我們可以看到我們將PizzaStore修改成抽象類,不同的披薩店繼承抽象類返回自己不同風(fēng)格的披薩。

          ? ?這樣設(shè)計(jì)后當(dāng)增加產(chǎn)品,我們也只是在具體的子類披薩店中修改其中的披薩創(chuàng)建,不會影響披薩店本身流程和其他披薩店的實(shí)現(xiàn)。

          ? 工廠方法模式:定義了一個創(chuàng)建對象的接口,由子類決定要實(shí)例化的類是哪一個,工廠方法讓類把實(shí)例化推遲到子類。

          ? 工廠方法與簡單工廠的區(qū)別:工廠方法的子類看起來很像簡單工廠。簡單工廠把全部的事情在一個地方處理完成,而工廠方法卻是創(chuàng)建一個框架,讓子類決定如何實(shí)現(xiàn)。

          3、披薩的不同原料

          不同風(fēng)格的披薩店有不同風(fēng)格的披薩,而這些披薩的不同風(fēng)格是來自不同原料造成,所以不同風(fēng)格的披薩變化的部分是材料。


          我們先建造原料和原料工廠,以中國披薩原料工廠為例
          //披薩原料工廠接口 public interface PizzaIngredientFactory { public Veggie
          CreateVeggie(); public Cheese CreateCheese(); } //具體工廠實(shí)現(xiàn) public class
          CNHPizzaIngredientFactory : PizzaIngredientFactory { public Cheese
          CreateCheese() { return new CHNCheese(); } public Veggie CreateVeggie() {
          return new CHNVeggie(); } } public abstract class Veggie { } public class
          USVeggie : Veggie { } public class CHNVeggie : Veggie { } public abstract class
          Cheese { } public class USCheese : Cheese { } public class CHNCheese : Cheese {
          }
            

            然后重做Pizza
          public abstract class Pizza { public String Name; Veggie veggie; Cheese
          cheese; //準(zhǔn)備 public abstract void Prepare(); //烘烤 public void Bake() { } //切片
          public void Cut() { } //裝盒 public void Box() { } }
            加入了原料的抽象 Veggie 和
          Cheese,同時我們讓Prepare變成抽象方法,讓他的具體子類決定用什么材制造不同風(fēng)格的披薩。接著我們重做子類,以CheesePizza為例?
          //奶酪披薩 public class CheesePizza : Pizza { PizzaIngredientFactory
          IngredientFactory; public CheesePizza(PizzaIngredientFactory IngredientFactory)
          { this.IngredientFactory = IngredientFactory; } public override void Prepare()
          { IngredientFactory.CreateCheese(); } }
            修改中國披薩店
          public class CHNSytlePizzaStore : PizzaStore { public override Pizza
          CreatePizza(string type) { Pizza pizza = null; //創(chuàng)建中國原材料工廠
          CNHPizzaIngredientFactory ingredientFactory = new CNHPizzaIngredientFactory();
          if (type == "cheese") { pizza = new CheesePizza(ingredientFactory); } else if
          (type == "viggie") { pizza = new VeggiePizza(ingredientFactory); } return
          pizza; } }
            

          通過這一系列的改造我們引入了新類型的工廠,也就是所謂的抽象工廠,抽象工廠用來創(chuàng)造原料。

          利用抽象工廠我們代碼將從實(shí)際工廠解耦,這樣如果我們的工廠需要擴(kuò)展那么我們則可在子類中進(jìn)行修改擴(kuò)展。

          工廠方法與抽象工廠的異同優(yōu)缺點(diǎn)

          相同:都是用來創(chuàng)建對象。

          不同:工廠方法使用的是繼承,抽象工廠使用的是組合。

          優(yōu)點(diǎn):工廠方法只負(fù)責(zé)從具體類型中解耦,抽象工廠適合將一群相關(guān)的產(chǎn)品集合起來。

          缺點(diǎn):抽象工廠擴(kuò)展接口需要修改每個子類。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點(diǎn)信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                豆花视频免费观看 | 日韩一区二区三区在线视频 | 日本大尺度吻视频 | 神马影院午夜福利 | 女版三国爆衣手游破解版 |