時間:2017年08月27日星期日
說明:本文部份內容均來自慕課網。@慕課網:http://www.imooc.com
教學源碼:https://github.com/zccodere/s...
學習源碼:https://github.com/zccodere/s...java
什麼是設計模式git
設計模式(Design pattern)是一套被反覆使用、多數人知曉的、通過分類編目的、代碼設計經驗的總結
應用設計模式的好處github
設計模式是優秀的使用案例 使用設計模式可提升代碼的重用性 讓代碼更容易被他人理解 保證代碼可靠性
重點內容編程
工廠模式的概念 工廠模式的意圖 工廠模式的應用場景 工廠模式的設計思想 工廠模式的好處
工廠模式概念設計模式
實例化對象,用工廠方法代替new操做 工廠模式包括工廠方法模式和抽象工廠模式 抽象工廠模式是工廠方法模式的擴展
工廠模式的意圖ide
定義一個接口來建立對象,可是讓子類來決定哪些類須要被實例化 工廠方法把實例化的工做推遲到子類中去實現
什麼狀況下適合工廠模式學習
有一組相似的對象須要建立 在編碼時不能預見須要建立哪一種類的實例 系統須要考慮擴展性,不該依賴於產品類實例若是被建立、組合和表達的細節
項目中的現狀編碼
在軟件系統中常常面臨着「對象」的建立工做,因爲需求的變化,這個對象可能隨之也會發生變化,但它卻擁有比較穩定的接口。爲此,咱們須要提供一種封裝機制來隔離出這個異變對象的變化,從而保持系統中其餘依賴該對象的對象不隨着需求變化而變化。
基於項目現狀將代碼進行以下設計spa
儘可能鬆耦合,一個對象的依賴對象的變化與自己無關 具體產品與客戶端剝離,責任分割
工廠方法模式類圖設計
抽象工廠模式類圖
代碼編寫
1.編寫HairInterface類
package com.myimooc.designpattern.c2factory.hair; /** * @describe 髮型接口 * @author zc * @version 1.0 2017-08-27 */ public interface HairInterface { /** * 畫髮型 */ void draw(); }
2.編寫LeftHair類
package com.myimooc.designpattern.c2factory.hair; /** * @describe 左偏分發型 * @author zc * @version 1.0 2017-08-27 */ public class LeftHair implements HairInterface { /** * 畫一個左偏分發型 */ @Override public void draw() { System.out.println("左偏分發型"); } }
3.編寫RightHair類
package com.myimooc.designpattern.c2factory.hair; /** * @describe 右偏分發型 * @author zc * @version 1.0 2017-08-27 */ public class RightHair implements HairInterface { /** * 畫一個右偏分發型 */ @Override public void draw() { System.out.println("右偏分發型"); } }
4.編寫InHair類
package com.myimooc.designpattern.c2factory.hair; /** * @describe 中偏分發型 * @author zc * @version 1.0 2017-08-27 */ public class InHair implements HairInterface{ @Override public void draw() { System.out.println("中偏分發型"); } }
5.編寫type.properties文件
left=com.myimooc.designpattern.c2factory.LeftHair right=com.myimooc.designpattern.c2factory.RightHair in=com.myimooc.designpattern.c2factory.InHair
6.編寫PropertiesReader類
package com.myimooc.designpattern.c2factory.hair; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * @describe properties文件讀取類 * @author zc * @version 1.0 2017-08-27 */ public class PropertiesReader { public Map<String,String> getProperties(){ Properties props = new Properties(); Map<String,String> map = new HashMap<String,String>(); try{ InputStream in = getClass().getResourceAsStream("type.properties"); props.load(in); @SuppressWarnings("unchecked") Enumeration<String> en = (Enumeration<String>) props.propertyNames(); while (en.hasMoreElements()) { String key = en.nextElement(); String property = props.getProperty(key); map.put(key, property); } in.close(); }catch (Exception e) { e.printStackTrace(); } return map; } }
7.編寫HairFactory類
package com.myimooc.designpattern.c2factory; import java.util.Map; import com.myimooc.designpattern.c2factory.hair.HairInterface; import com.myimooc.designpattern.c2factory.hair.LeftHair; import com.myimooc.designpattern.c2factory.hair.PropertiesReader; import com.myimooc.designpattern.c2factory.hair.RightHair; /** * @describe 髮型工廠 * @author zc * @version 1.0 2017-08-27 */ public class HairFactory { /** * 根據類型來建立對象 * @param key * @return */ public HairInterface getHair(String key){ if("left".equals(key)){ return new LeftHair(); } else if("right".equals(key)){ 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) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * 根據類的名稱來生產對象 * @param className * @return */ public HairInterface getHairByClassKey(String key){ try { Map<String,String> map = new PropertiesReader().getProperties(); HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance(); return hair; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
8.編寫Test類
package com.myimooc.designpattern.c2factory; import com.myimooc.designpattern.c2factory.hair.HairInterface; /** * @describe 模擬客戶端實現 * @author zc * @version 1.0 2017-08-27 */ public class Test { public static void main(String[] args) { // HairInterface left = new LeftHair(); // left.draw(); // // HairInterface right = new RightHair(); // right.draw(); HairFactory factory = new HairFactory(); // HairInterface left = factory.getHair("left"); // left.draw(); HairInterface left = factory.getHairByClass("com.myimooc.designpattern.c2factory.LeftHair"); left.draw(); // HairInterface hair = factory.getHairByClassKey("in"); // hair.draw(); } }
代碼編寫
1.編寫Boy類
package com.myimooc.designpattern.c2factory.boy; /** * @describe 男孩 * @author zc * @version 1.0 2017-08-27 */ public interface Boy { void drawMan(); }
2.編寫HnBoy類
package com.myimooc.designpattern.c2factory.boy; /** * @describe 新年系列的男孩 * @author zc * @version 1.0 2017-08-27 */ public class HnBoy implements Boy { @Override public void drawMan() { System.out.println("新年系列的男孩"); } }
3.編寫McBoy類
package com.myimooc.designpattern.c2factory.boy; /** * @describe 聖誕系列的男孩 * @author zc * @version 1.0 2017-08-27 */ public class McBoy implements Boy { @Override public void drawMan() { System.out.println("聖誕系列的男孩"); } }
4.編寫Girl類
package com.myimooc.designpattern.c2factory.girl; /** * @describe 女孩 * @author zc * @version 1.0 2017-08-27 */ public interface Girl { void drawWomen(); }
5.編寫HnGril類
package com.myimooc.designpattern.c2factory.girl; /** * @describe 新年系列的女孩 * @author zc * @version 1.0 2017-08-27 */ public class HnGril implements Girl { @Override public void drawWomen() { System.out.println("新年系列的女孩"); } }
6.編寫McGril類
package com.myimooc.designpattern.c2factory.girl; /** * @describe 聖誕系列的女孩 * @author zc * @version 1.0 2017-08-27 */ public class McGril implements Girl { @Override public void drawWomen() { System.out.println("聖誕系列的女孩"); } }
7.編寫PersonFactory類
package com.myimooc.designpattern.c2factory; import com.myimooc.designpattern.c2factory.boy.Boy; import com.myimooc.designpattern.c2factory.girl.Girl; /** * @describe 人物的實現接口 * @author zc * @version 1.0 2017-08-27 */ public interface PersonFactory { // 獲取男孩接口 Boy getBoy(); // 獲取女孩接口 Girl getGirl(); }
8.編寫HnFactory類
package com.myimooc.designpattern.c2factory; import com.myimooc.designpattern.c2factory.boy.Boy; import com.myimooc.designpattern.c2factory.boy.HnBoy; import com.myimooc.designpattern.c2factory.girl.Girl; import com.myimooc.designpattern.c2factory.girl.HnGril; /** * @describe 新年系列加工廠 * @author zc * @version 1.0 2017-08-27 */ public class HnFactory implements PersonFactory { @Override public Boy getBoy() { return new HnBoy(); } @Override public Girl getGirl() { return new HnGril(); } }
9.編寫McFactory類
package com.myimooc.designpattern.c2factory; import com.myimooc.designpattern.c2factory.boy.Boy; import com.myimooc.designpattern.c2factory.boy.McBoy; import com.myimooc.designpattern.c2factory.girl.Girl; import com.myimooc.designpattern.c2factory.girl.McGril; /** * @describe 聖誕系列加工廠 * @author zc * @version 1.0 2017-08-27 */ public class McFactory implements PersonFactory { @Override public Boy getBoy() { return new McBoy(); } @Override public Girl getGirl() { return new McGril(); } }
10.修改Test類
package com.myimooc.designpattern.c2factory; import com.myimooc.designpattern.c2factory.boy.Boy; import com.myimooc.designpattern.c2factory.girl.Girl; import com.myimooc.designpattern.c2factory.hair.HairInterface; /** * @describe 模擬客戶端實現 * @author zc * @version 1.0 2017-08-27 */ public class Test { public static void main(String[] args) { // HairInterface left = new LeftHair(); // left.draw(); // // HairInterface right = new RightHair(); // right.draw(); HairFactory factory = new HairFactory(); // HairInterface left = factory.getHair("left"); // left.draw(); HairInterface left = factory.getHairByClass("com.myimooc.designpattern.c2factory.LeftHair"); left.draw(); // HairInterface hair = factory.getHairByClassKey("in"); // hair.draw(); testPerson(); } public static void testPerson(){ PersonFactory factory = new McFactory(); Girl girl = factory.getGirl(); girl.drawWomen(); factory = new HnFactory(); Boy boy = factory.getBoy(); boy.drawMan(); } }
場景應用
Spring BeanFactory
BeanFactory,做爲Spring基礎的IOC容器,是Spring的一個Bean工廠 若是單從工廠模式的角度思考,它就是用來「產生Bean」,而後提供給客戶端
Bean的實例化過程以下
調用Bean的默認構造方法,或指定的構造方法,生成bean實例(暫稱爲instance1) 若是Bean的配置文件中注入了Bean屬性值,則在instance1基礎上進行屬性注入造成instance2,這種注入是覆蓋性的 若是Bean實現了InitializingBean接口,則調用afterPropertiesSet()方法,來改變或操做instance2,獲得instance3 若是Bean的配置文件中指定了init-method=」init」屬性,則會調用指定的初始化方法, 則在instance3的基礎上調用初始化方法init(),將對象最終初始化爲instance4;固然,這個初始化的名字是任意的
工廠方法模式和抽象工廠模式對比
工廠模式是一種極端狀況下的抽象工廠模式,而抽象工廠模式能夠當作是工廠模式的推廣 工廠模式用來建立一個產品的等級結構,而抽象工廠模式是用來建立多個產品的等級結構 工廠模式只有一個抽象產品類,而抽象工廠模式有多個抽象產品類
工廠模式的實現幫助咱們
系統能夠在不修改具體工廠角色的狀況下引進新的產品 客戶端沒必要關係對象如何建立,明確了職責 更好的理解面向對象的原則,面向接口編程,而不要面向實現編程
工廠模式適用於哪些場景
一個系統應當不依賴於產品類實例被創立、組成和表示的細節。這對全部形態的工廠模式都是重要的 這個系統的產品有至少一個的產品族 同屬於一個產品族的產品是設計成在一塊兒使用的。這一約束必須得在系統的設計中體現出來 不一樣的產品以一系列的接口的面貌出現,從而使系統不依賴於接口實現的細節