關於設計模式(主要是思想方面)
001.定義:
是一套反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結
002.目的:
爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性
設計模式之工廠模式:
定義:
實例化對象,用工廠方法來代替new操作(創建我們需要的事物供我們使用)
分類:
工廠方法模式、抽象工廠模式
設計意圖:
定義一個用於創建對象的接口,讓子類決定實例化哪一些類。工廠方法使一個類的實例化延遲到其子類
特點:
將創建實例的工作與使用實例的工作分離開,低耦合
何時使用:
01.有一組類似的對象需要創建
02.編碼時不能預見那種類型的對象需要創建實例
03.系統需要考慮擴展性,不應依賴於產品類實例如何被創建、組合和表達的細節
動機:
代碼之間實現鬆耦合,一個對象的依賴對象的變化與本身無關
具體產品與客戶端剝離,責任分割
生活場景:
01.比如你想做一兩蘭博基尼,你只需要告訴你的工廠我需要蘭博基尼,工廠就會完成複雜的建造過程,最終把產品給你,也可以構建其他汽車,你只要告訴工長你需要什麼車即可;
02.比如早晨起來刷牙洗臉,你用到的毛巾,你想要什麼樣的毛巾,你只需要去告訴工廠即可,它會返回你想要的毛巾,其他過程不用處理
工廠方法模式類圖:
分析 ----> 客戶端下命令需要生產水果,creator就負責生產水果(利用factory生產Iproduct水果,水果下面就有很多水果:product1、product2),具體是由客戶端決定創建什麼水果
抽象工廠模式類圖:
分析 ----> 客戶端發命令,我需要什麼產品,工廠有兩個類系,他們都能創建客戶端的產品,可以理解爲家族與系列產品
兩種的區別與聯繫:
分析 ----> 抽象工廠模式是工廠方法模式的擴展
一個具體的工程可以生產一個對應的產品族,即工廠方法模式,多個工廠(產品族)就是抽象工廠模式
代碼實現工廠方法模式:
Factory:
/** * 髮型工廠:生成髮型,不用客戶端顯式的調用 */ public class HairFactory { /** * 根據類型來創建對象 * * @param hair * @return */ public HairInterface getHair(String hair) { if ("left".equals(hair)) { return new LeftHair(); } else if ("right".equals(hair)) { return new RightHair(); } return null;//兩種情況都不符合返回空 } /** * 根據類名生產對象 * * @param className * @return */ public HairInterface getHairByClass(String className) { try { //利用反射生成類的名稱 HairInterface hair = (HairInterface) Class.forName(className).newInstance(); return hair;//獲取成功 } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null;//獲取失敗返回null } }
產品(髮型)接口:
/** * 髮型接口:左偏分、右偏分等等 */ public interface HairInterface { //實現了:繪製髮型 void draw(); }
具體的產品1(左偏分)
/** * 左偏分發型 */ public class LeftHair implements HairInterface { private static final String TAG = "LeftHair"; //畫了一個左偏分發型 @Override public void draw() { Log.i(TAG, "draw: " + "左偏分發型"); } }
具體的產品2(右偏分)
/** * 有偏分發型 */ public class RightHair implements HairInterface { private static final String TAG = "RightHair"; //畫了一個右偏分發型 @Override public void draw() { Log.i(TAG, "draw: " + "右偏分發型"); } }
創建實例:
private void showHair() { // 1.0:普通方法:每次需要一個髮型都會創建一個新的hair,而且在客戶端顯式的調用,這樣的 // 的代碼既不利於維護也不利於管理 HairInterface left = new LeftHair(); left.draw(); //2.0:工廠模式創建:集中到HairFactory工廠中管理,產品的實現與客戶端分離(不用顯式的調用), // 現在只要告訴我需要左偏分或右偏分HairFactory就可以幫我創建 // 缺點:每多一種髮型就要進行判斷生成對應的髮型,不能智能的根據髮型的類型幫我們創建 HairFactory factory = new HairFactory(); HairInterface left = factory.getHair("left"); if (left != null) { left.draw(); } //3.0利用類的對象創建對象:如果我們再增加發型,我們只需要增加發型的類並且告知客戶端我們有這個類, //我們就可以用這個類做事情 HairFactory factory = new HairFactory(); HairInterface left = factory.getHairByClass("com.test.okamiy.factorymode.myotee.LeftHair");//包名全路徑 if (null != left) { left.draw(); } }
代碼實現抽象工廠模式:
抽象工廠:PersonFactory
/** * 人物的實現接口 */ public interface PersonFactory { //男孩接口 public Boy getBoy(); //女孩接口 public Girl getGirl(); }
新年系類工廠:
/** * 新年系列加工廠 */ public class HNFactory implements PersonFactory { @Override public Boy getBoy() { return new HNBoy(); } @Override public Girl getGirl() { return new HNGirl(); } }
新年系列的具體對象(新年系列的女子)
/** * 新年系列的女孩子 */ public class HNGirl implements Girl { @Override public void drawWomen() { System.out.println("-----------------新年系列的女孩子--------------------"); } }
新年系列的具體對象(新年系列的男子)
/** * 新年系列的男孩子 */ public class HNBoy implements Boy { @Override public void drawMan() { System.out.println("-----------------新年系列的男孩子--------------------"); } }
聖誕系類工廠
/** * 聖誕系列加工廠 */ public class MCFctory implements PersonFactory { @Override public Boy getBoy() { return new MCBoy(); } @Override public Girl getGirl() { return new MCGirl(); } }
聖誕系列的具體對象(聖誕系列的女子)
/** * 聖誕系列的女孩 */ public class MCGirl implements Girl { @Override public void drawWomen() { System.out.println("-----------------聖誕系列的女孩--------------------"); } }
聖誕系列的具體對象(聖誕系列的男子)
/** * 聖誕系列的男孩子 */ public class MCBoy implements Boy { @Override public void drawMan() { System.out.println("-----------------聖誕系列的男孩子--------------------"); } }
女孩接口
/** * 女孩 */ public interface Girl { public void drawWomen(); }
男孩接口
/** * 男孩 */ public interface Boy { public void drawMan(); }
最終的測試:
private void test() { PersonFactory facoty = new HNFactory(); Boy boy = facoty.getBoy(); boy.drawMan(); }打印“-----------------新年系列的男孩子--------------------”
總結:通過以上兩組代碼做出分析
分析一:從兩種工廠模式對比
a. 工廠方法模式是一種極端的抽象工廠模式,而抽象工廠模式可以看成是工廠模式的推廣
b. 工廠方法模式用來創建一個產品的等級結構,而抽象工廠模式是用來創建多個產品的等級結構
c. 工廠方法模式只有一個抽象類,而抽象工廠模式有多個抽象產品類
d. 工廠模式方法是有一個抽象的父類定義的公共接口,子類負責生成具體的對象,這樣做的目的是將類的實例化操作延遲到子類當中完成
e. 抽象工廠模式提供一個創建一系列相關或相互依賴對象的接口,而無需指定他們具體的類,它針對的是有多個產品的等級結構,而工廠方法模式針對的是一個產品的等級結構
分析二:從工廠模式優點
a. 系統可以在不修改具體工廠角色的情況下引進新的產品
b. 客戶端不必關心對象的創建,明確職責
c. 更好的理解面向對象的原則、面向接口編程,而不是面向實現編程
分析三:從工廠模式使用場景
a. 一個系統應當不依賴於產品實例的創建、組成和表示細節,這對於所有形態的工廠模式都是很重要的
b. 這個系統的產品有至少一個產品族
c. 同屬於一個產品族的產品是設計在一起使用的,這一約束必須得在系統的設計中提現出來
d. 不同的產品以一系列的接口的面貌出現,從而使得系統不依賴與接口的實現細節
Last:本篇參照慕課網視頻學習,有不懂的可以去慕課網看視頻學習!
歡迎探討學習,真心希望大家推薦好文共同成長!