走進設計模式的世界4:我不是你,但是大家都把我當成你-工廠模式和抽象工廠模式
阿新 • • 發佈:2018-11-14
工廠模式和抽象工廠模式:
工廠方法模式:定義了一個建立物件的介面,但由子類決定要例項化的類是哪一個。工廠方法讓類把例項化推遲到之類。
抽象工廠模式:提供一個介面,用於建立相關或以來物件的家族,而不需要明確指定具體類。
解釋:工廠方法使用繼承把物件的建立交給之類,子類實現工廠方法來建立物件。抽象工廠使用物件的組合:物件的建立被實現在工廠介面所暴露出來的方法中。所有工廠模式都通過減少應用程式和具體類間的依賴促進鬆耦合。工廠方法允許類將例項化延遲到子類進行。抽象工廠建立相關的物件家族,而不需要依賴他們的具體類。依賴倒置原則,指導我們避免依賴具體型別,儘量依賴抽象。
設計原則:依賴抽象,不要依賴具體類。
以一個餃子店的業務為例。通過對不同業務的整合,分別完成工廠模式和抽象工廠模式。
以下是針對製作不同的餃子進行的工廠模式的設計。
/** 這是一個餃子的工廠父類,用於餃子的建立 **/ public abstract JiaoZiFactory{ /** 生成餃子 **/ public orderJiaoZi(){ // 做餡料 doFillings(); // 包餃子 makeJiaoZi(); // 煮餃子 boilingJiaoZi(); } /** 做餡料(抽象,交由子類實現) **/ public JiaoZi doFillings(); /** 包餃子 **/ public JiaoZi makeJiaoZi(){ System.out.println("餃子包好了"); } /** 煮餃子 **/ public JiaoZi boilingJiaoZi(){ System.out.println("餃子煮好了,上菜。"); } } /** 餃子類的基類 **/ public class JiaoZi { private String[] fillings(); } /** 韭菜雞蛋餃子 **/ public class JiuCaiJiDanJiaoZi{ } /** 韭菜蝦仁餃子 **/ public class JiuCaiXiaRenJiaoZi{ } /** 牛肉餃子 **/ public class NiuRouJiaoZi{ } /** 韭菜雞蛋餃子工廠 **/ public JiuCaiJiDanJiaoZiFactory extends JiaoZiFactory{ public JiaoZi doFillings(){ fillings.add("韭菜"); fillings.add("雞蛋"); } } /** 韭菜蝦仁餃子工廠 **/ public JiuCaiXiaRenFactory extends JiaoZiFactory{ public JiaoZi doFillings(){ fillings.add("韭菜"); fillings.add("蝦仁"); } } /** 牛肉餃子工廠 **/ public NiuRouFactory extends JiaoZiFactory{ public JiaoZi doFillings(){ fillings.add("牛肉"); fillings.add("洋蔥"); } } public class Test{ public static void main(String[]args){ JiaoZiFactory factory = new NiuRouFactory(); factory.orderJiaoZi(); } }
以下是針對餃子原材料進行的抽象工廠的設計。
/** 製作餃子需要2種原材料 皮/餡料 下面是餃子的工廠類設計 **/ public class JiaoZiFactory{ // 把原料工廠當作一個屬性,提供介面 利用組合的方式 private YuanLiaoFactory yuanLiaoFactory; // 工廠的建立指定不同的原料工廠 public JiaoZiFactory (YuanLiaoFactory yuanliaoFactory){ this.yuanLiaoFactory = yuanLiaoFactory; } // 獲取餃子 public JiaoZi orderJiaozi(){ Jiaozi jiaozi = new Jiaozi(); jiaozi = yuanLiaoFactory.createPi(); jiaozi = yuanLiaoFactory.createXian(); return jiaozi; } } /** 製作餃子原料的工廠 **/ public interface yuanLiaoFactory(){ // 製造皮的方法 JiaoZi createPi(Jiaozi jiaozi); // 製造餡料的方法 JiaoZi createXian(Jiaozi jiaozi); } /** 南方餃子工廠 **/ public class NanJiaoZiFactory(){ public JiaoZi createPi(Jiaozi jiaozi){ jiaozi.setPi("南方餃子皮"); } public JiaoZi createXian(Jiaozi jiaozi){ jiaozi.setXian("南方餃子餡料"); } } /** 北方餃子工廠 **/ public class BeiJiaoZiFactory(){ public JiaoZi createPi(Jiaozi jiaozi){ jiaozi.setPi("北方餃子皮"); } public JiaoZi createXian(Jiaozi jiaozi){ jiaozi.setXian("北方餃子餡料"); } } /** 餃子實體類 **/ public class JiaoZi{ // 皮 private String Pi; // 餡料 private String Xian; // 省略get,set } public class Test{ public static void main(String[]agrs){ // 餃子工廠(南餃子原料) JiaoZiFactory factory = new JiaoZiFactory(new NanJiaoZiFactory()); // 南餃子 JiaoZi jiaozi1 = factory.orderJiaozi(); // 更換原料工廠(北餃子原料) factory = new JiaoZiFactory(new BeiJiaoZiFactory()); // 北餃子 JiaoZi jiaozi2 = factory.orderJiaozi(); } }
總結:雖然工廠模式和抽象工廠模式有很多類似之處。都是為了將物件解耦。工廠模式使用的是繼承的方式,實現物件的解耦,而抽象工廠模式是使用組合的方式進行物件的解耦。工廠模式適用於某個產品,而抽象工廠適用於某個產品家族,他們還是有很多區別的。