工厂模式---设计模式(二)
工廠方法模式:
定義:
定義一個用于創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。
解決的使項目中的實例化問題,一般我們是在某個地方用到某個類就new一個。工廠模式解決的是大量的實例化某些、某種、某批類的對象。
類圖:
通用代碼:
抽象產品類:
具體產品類:
具體產品類可以有多個,都繼承于抽象產品類。
抽象工廠類:
抽象工廠類負責定義產品對象的產生。
具體工廠類:
具體如何產生一個產品的對象,是由具體的工廠類實現的。
場景類:
package com.test.Test;public class Client {public static void main(String[] args) {Creator creator = new ConcreteCreator();Product product = creator.createProduct(ConcreteProduct1.class);/** 繼續業務處理*/}}例子:
抽象產品類:
package com.test.teaAndmilk;/*** 奶茶(抽象產品類)* 2015年9月18日 下午5:19:01* @author 張耀暉**/ public abstract class TeaAndMilk {//奶茶類的抽象方法,由具體的子類來實現public abstract void prepare();//奶茶類的公共方法public void doWater(){System.out.println("加入水。。。");}public void doMix(){System.out.println("攪拌均勻。。。");}public void doCapping(){System.out.println("封裝加蓋。。。完成");}}具體產品類:
package com.test.teaAndmilk;/*** 綠茶(具體產品類)* 2015年9月18日 下午5:34:17* @author 張耀暉**/ public class GreenTea extends TeaAndMilk {@Overridepublic void prepare() {System.out.println("加入綠茶所用的茶葉。。。");}} package com.test.teaAndmilk;/*** 珍珠奶茶(具體產品類)* 2015年9月18日 下午5:34:42* @author 張耀暉**/ public class GemMilk extends TeaAndMilk {@Overridepublic void prepare() {System.out.println("加入珍珠奶茶需要的材料。。。");}}抽象工廠類:
package com.test.Factory;import com.test.teaAndmilk.TeaAndMilk;/*** 抽象奶茶創建工廠(抽象工廠類)* 2015年9月18日 下午5:34:08* @author 張耀暉**/ public abstract class FactoryCreator {public abstract <T extends TeaAndMilk> T createTeaAndMilk(Class<T> c);}具體工廠類:
package com.test.Factory;import com.test.teaAndmilk.TeaAndMilk;/*** 奶茶創建工廠(具體工廠類)* 2015年9月18日 下午5:38:14* @author 張耀暉**/ public class TeaAndMilkFactory extends FactoryCreator{@Overridepublic <T extends TeaAndMilk> T createTeaAndMilk(Class<T> c) {TeaAndMilk teaAndmilk = null;try {teaAndmilk = (TeaAndMilk) Class.forName(c.getName()).newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return (T)teaAndmilk;}}場景類:
package com.test.client;import com.test.Factory.FactoryCreator; import com.test.Factory.TeaAndMilkFactory; import com.test.teaAndmilk.GreenTea; import com.test.teaAndmilk.TeaAndMilk; /*** 奶茶店(場景類)* 2015年9月18日 下午5:46:05* @author 張耀暉**/ public class Client {public static void main(String[] args) {FactoryCreator creator = new TeaAndMilkFactory();//如果顧客需要綠茶TeaAndMilk teaAndmilk = creator.createTeaAndMilk(GreenTea.class);//具體的業務處理teaAndmilk.prepare();teaAndmilk.doWater();teaAndmilk.doMix();teaAndmilk.doCapping();}}運行結果:
工廠方法模式的優點:
大家應該能夠深刻體會到工廠方法模式的好處:如果使用JDBC連接數據庫,數據庫從MySql切換到Oracle,需要改動地方就是切換一下驅動名稱(前提條件是SQL語句是標準語句),其他的都不需要修改,這是工廠方法模式靈活性的一個直接案例。
工廠方法模式的使用場景:
工廠方法模式是new一個對象的替代品,所以在所有需要生成對象的地方都可以使用,但是需要慎重的考慮是否要增加一個工廠類來進行管理,增加代碼的復雜度。
工廠方法模式的擴展:
縮小為簡單工廠模式:
簡單工廠模式:定義一個創建對象的類,由這個類來實例化對象的行為。
上例更改為簡單工廠模式:
簡單工廠模式中的工廠類:
簡單工廠模式中的場景類:
package com.test.easyFactory;import com.test.teaAndmilk.GemMilk; import com.test.teaAndmilk.TeaAndMilk;/*** 奶茶店(場景類)* 2015年9月18日 下午7:21:00* @author 張耀暉**/ public class Client {public static void main(String[] args) {TeaAndMilk teaAndMilk = EasyFactory.createTeaAndMilk(GemMilk.class);teaAndMilk.prepare();teaAndMilk.doWater();teaAndMilk.doMix();teaAndMilk.doCapping();}}運行結果:
分析與工廠方法模式的不同之處:
抽象工廠模式
定義:
為創建一組相關或相互依賴的對象提供一個接口,而且無須指定它們的具體類。
通用類圖:
通用源碼類圖:
AbstractProductA和AbstractProductB兩個抽象產品類可以有關系,例如共同繼承一個抽象類或接口。
通用源碼:
抽象產品類:
兩個具體的產品實現類
產品A1的實現類:
產品A2的實現類:
package com.test.Test;public class ProductA2 extends AbstractProductA {@Overridepublic void doSomething() {System.out.println("產品A2的實現方法");}}產品B與此類似,代碼省略了。
抽象工廠類:
抽象工廠類AbstractCreator的職責是定義每個工廠要實現的功能
該抽象工廠類定義了兩個產品族的產品創建。
注意: 有N個產品族,在抽象工廠類中就應該有N個創建方法。
產品等級1的實現類:
如何創建一個產品,則是有具體的實現類來完成的。
注意: 有M個產品等級就應該有M個實現工廠類,在每個實現工廠中,實現不同產品族的生產任務。
產品等級2的實現類:
package com.test.Test;public class Creator2 extends AbstractCreator {// 只生產產品等級為2的A產品public AbstractProductA createProductA() {return new ProductA2();}// 只生產產品等級為2的B產品public AbstractProductB createProductB() {return new ProductB2();}}場景類:
package com.test.Test;public class Client {public static void main(String[] args) {// 定義出兩個工廠AbstractCreator creator1 = new Creator1();AbstractCreator creator2 = new Creator2();// 產生A1對象AbstractProductA a1 = creator1.createProductA();// 產生A2對象AbstractProductA a2 = creator2.createProductA();// 產生B1對象AbstractProductB b1 = creator1.createProductB();// 產生B2對象AbstractProductB b2 = creator2.createProductB();/** * * * 然后在這里就可以為所欲為了...*/}}具體的應用實例:
人種接口:
package com.test.human;/*** 人種接口* 2015年9月18日 下午8:50:17* @author 張耀暉**/ public interface Human {// 每個人種都有相應的顏色public void getColor();// 人類都會說話public void talk();// 每個人都有性別public void getSex(); }人種有三個抽象類,負責人種的抽象屬性定義:膚色和語言,白色人種、黑色人種、黃色人種
白色人種:
黃色人種:
package com.test.human;/*** 黃色人種* 2015年9月18日 下午8:55:34* @author 張耀暉**/ public abstract class AbstractYellowHuman implements Human {@Override//黃色人種的皮膚顏色為黃色public void getColor() {System.out.println("黃色人種的皮膚顏色為黃色!");}@Override//黃色人種講話public void talk() {System.out.println("黃色人種會講話,一般說的都是雙字節!");}}黑色人種:
package com.test.human;/*** 黑色人種* 2015年9月18日 下午8:53:15* @author 張耀暉**/ public abstract class AbstractBlackHuman implements Human {@Override//黑色人種的皮膚顏色為黑色public void getColor() {System.out.println("黑色人種的皮膚顏色為黑色!");}@Override//黑色人種講話public void talk() {System.out.println("黑色人種會講話,一般人聽不懂!");}}每個抽象類都有兩個實現類,分別實現公共的最細節、最具體的事物:膚色和語言。具體的實現類膚色性別定義,以黃色女性人種為例。
其他的黑色人種、白色人種的男性和女性的代碼與此類似,不再重復編寫。
黃色女性人種:
黃色男性人種:
package com.test.human;/*** 黃色男性人種* 2015年9月18日 下午8:59:06* @author 張耀暉**/ public class MenYellowHuman extends AbstractYellowHuman {@Override//黃人男性public void getSex() {System.out.println("黃人男性");}}八卦爐定義:
package com.test.factory;import com.test.human.Human;/*** 八卦爐定義* 2015年9月18日 下午9:03:35* @author 張耀暉**/ public interface HumanFactory {//制造一個黃色人種public Human createYellowHuman();//制造一個黑色人種public Human createBlackHuman();//制造一個白色人種public Human createWhiteHuman(); }具體的八卦爐:
生產女性的八卦爐:
生產男性的八卦爐:
package com.test.factory;import com.test.human.Human; import com.test.human.MenBlackHuman; import com.test.human.MenWhiteHuman; import com.test.human.MenYellowHuman;/*** 生產男性的八卦爐* 2015年9月18日 下午9:11:20* @author 張耀暉**/ public class MenFactory implements HumanFactory {@Override//生產出黃人男性public Human createYellowHuman() {return new MenYellowHuman();}@Override//生產出黑人男性public Human createBlackHuman() {return new MenBlackHuman();}@Override//生產出白人男性public Human createWhiteHuman() {return new MenWhiteHuman();}}女媧類(場景類):
package com.test.Client;import com.test.factory.HumanFactory; import com.test.factory.MenFactory; import com.test.factory.WomenFactory; import com.test.human.Human;/*** 女媧造人* 2015年9月18日 下午9:18:56* @author 張耀暉**/ public class NvWa {public static void main(String[] args) {//第一條生產線,男性生產線HumanFactory menFactory = new MenFactory();//第二條生產線,女性生產線HumanFactory womenFactory = new WomenFactory();//生產線建立完畢,開始生產人Human menYellowHuman = menFactory.createYellowHuman();Human womenYellowHuman = womenFactory.createYellowHuman();menYellowHuman.getColor();menYellowHuman.talk();menYellowHuman.getSex();womenYellowHuman.getColor();womenYellowHuman.talk();womenYellowHuman.getSex();//下面繼續創建黑人和白人的男性和女性。。。。。。}}運行結果:
抽象工廠模式的使用場景
抽象工廠模式的使用場景定義非常簡單:一個對象族(或是一組沒有任何關系的對象)都有相同的約束,則可以使用抽象工廠模式,什么意思呢?例如一個文本編輯器和一個圖片處理器,都是軟件實體,但是*nix下的文本編輯器和WINDOWS下的文本編輯器雖然功能和界面都相同,但是代碼實現是不同的,圖片處理器也是類似情況,也就是具有了共同的約束條件:操作系統類型,于是我們可以使用抽象工廠模式,產生不同操作系統下的編輯器和圖片處理器。
總結
以上是生活随笔為你收集整理的工厂模式---设计模式(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单例模式---设计模式(一)
- 下一篇: XML解析的三种方式(dom,sax,d