設計模式之工廠模式 (二)
工廠模式分為三大類
- 簡單工廠(SimpleFactory)
- 工廠方法模式(Factory Method)
- 抽象工廠模式(Abstract Factory)
- 動態工廠(Dynamic Factory。屬於優化版簡單工廠)
目的:
工廠模式主要是為創建對象提供過渡接口。以便將創建對象的詳細過程屏蔽隔離起來,達到提高靈活性的目的。
一、簡單工廠
組成例如以下:
(1) 工廠類角色:這是本模式的核心。含有一定的商業邏輯和推斷邏輯。在java中它往往由一個詳細類實現。
詳細樣例:
抽象產品、詳細產品角色類定義例如以下:
package com.open.design.factory; public class SimpleFactoryData { //2.抽象產品角色:它通常是詳細產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。 public interface Car { void printName(); } //3.詳細產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個詳細類實現。 public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }
package com.open.design.factory; import com.open.design.factory.SimpleFactoryData.Car; //1.工廠類角色:這是本模式的核心,含有一定的商業邏輯和推斷邏輯。在java中它往往由一個詳細類實現 public class SimpleFactory { public static Car produce(String carName) { Car car=null; if("Benz".equals(carName)) { car=new SimpleFactoryData.Benz(); } else if("BMW".equals(carName)) { car=new SimpleFactoryData.BMW(); } else if("Audi".equals(carName)) { car=new SimpleFactoryData.Audi(); } else if("Tesla".equals(carName)) { car=new SimpleFactoryData.Tesla(); } return car; } }
package com.open.design.factory; import com.open.design.factory.SimpleFactoryData.Car; public class SimpleFactoryTest { /** * @param args */ public static void main(String[] args) { Car car=SimpleFactory.produce("Benz"); car.printName(); car=SimpleFactory.produce("BMW"); car.printName(); car=SimpleFactory.produce("Audi"); car.printName(); car=SimpleFactory.produce("Tesla"); car.printName(); } }
打印結果例如以下:
長處與缺點:
簡單工廠方法的長處是當在系統中引入新產品時不必改動client,但須要個改動工廠類。這個工廠類集中了全部產品創建邏輯。形成了一個無所不知的全能類(也稱上帝類),假設此類出問題了,整個應用都受大影響。
二、工廠方法模式(也稱多態工廠)
組成例如以下:
由應用程序調用以創建相應的詳細產品的對象。
詳細樣例例如以下:
抽象產品、詳細產品角色類定義例如以下:
package com.open.design.factory; public class PolymorphicData { //3.抽象產品角色:它是詳細產品繼承的父類或者是實現的接口。在java中一般有抽象類或者接口來實現。public interface Car { void printName(); } //4.詳細產品角色:詳細工廠角色所創建的對象就是此角色的實例。在java中由詳細的類來實現。 public static class Sedan implements Car { @Override public void printName() { System.out.println("i am Sedan."); } } public static class Train implements Car { @Override public void printName() { System.out.println("i am Train."); } } public static class Bike implements Car { @Override public void printName() { System.out.println("i am Bike."); } } }
抽象工廠、詳細工廠類定義例如以下:
package com.open.design.factory; import com.open.design.factory.PolymorphicData.Car; public class PolymorphicFactory { //1.抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是詳細工廠角色必須實現的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現。 public static abstract class CarFactory { abstract Car createCar(); } //2.詳細工廠角色:它含有和詳細業務邏輯有關的代碼。由應用程序調用以創建相應的詳細產品的對象。 public static class SedanFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Sedan(); }; } public static class TrainFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Train(); }; } public static class BikeFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Bike(); }; } }
測試類例如以下:
package com.open.design.factory; import com.open.design.factory.PolymorphicData.Car; import com.open.design.factory.PolymorphicFactory.BikeFactory; import com.open.design.factory.PolymorphicFactory.CarFactory; import com.open.design.factory.PolymorphicFactory.SedanFactory; import com.open.design.factory.PolymorphicFactory.TrainFactory; public class PolymorphicTest { /** * @param args */ public static void main(String[] args) { CarFactory factory=new SedanFactory(); Car car =factory.createCar(); car.printName(); factory=new TrainFactory(); car =factory.createCar(); car.printName(); factory=new BikeFactory(); car =factory.createCar(); car.printName(); } }
打印結果:
長處與缺點:
當在系統中引入新產品時,既不必改動client。又不必改動詳細工廠角色能夠較好的對系統進行擴展。可是當產品種類繁多時。工廠類成倍數增長(由於種類越多,與之相應的工廠類也越多)
在工廠方法模式中,核心的工廠類不再負責全部產品的創建,而是將詳細創建的工作交給子類去做。這個核心工廠則變為抽象工廠角色,僅負責給出具工廠子類必須實現的接口,而不接觸哪一產品創建的細節。
這樣的抽象的結果,使這樣的工廠方法模式能夠用來同意系統不改動詳細工廠角色的情況下引進新產品,這一特點無疑使得工廠模式具有超過簡單工廠模式的優越性。
三、抽象工廠
組成與工廠方法模式一致,僅僅只是抽象工廠是針對多個產品等級結構,工廠方法是針對一個產品等級結構。(產品族:是指位於不同產品等級結構中,功能相關聯的產品組成的家族。比方AMD的CPU和ADM芯片的主板,組成一個家族。Intel的CPU和Intel芯片的主板,又組成一個家族。而這兩個家族都來自於兩個產品等級:CPU,主板。)
詳細樣例例如以下:
抽象產品、詳細產品角色類定義例如以下:
package com.open.design.factory; public class AbstractFactryCar { //2.抽象產品角色:它通常是詳細產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。 public interface Car { void printName(); } //3.詳細產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個詳細類實現。 public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }
package com.open.design.factory; public class AbstractFactryHouse { //2.抽象產品角色:它通常是詳細產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。public interface House { void printHouseName(); } //3.詳細產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個詳細類實現。 public static class Villa implements House { @Override public void printHouseName() { System.out.println("i am Villa."); } } public static class TileRoofedHouse implements House { @Override public void printHouseName() { System.out.println("i am TileRoofedHouse."); } } public static class CommodityHouse implements House { @Override public void printHouseName() { System.out.println("i am CommodityHouse."); } } }
抽象工廠、詳細工廠類定義例如以下:
package com.open.design.factory; import com.open.design.factory.AbstractFactryCar.Car; import com.open.design.factory.AbstractFactryHouse.House; public class AbstractFactry { //抽象工廠類 public static abstract class AbsDream { public abstract Car createCar(); public abstract House createHouse(); } //2.詳細工廠角色:它含有和詳細業務邏輯有關的代碼。由應用程序調用以創建相應的詳細產品的對象。
public static class DreamAFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Benz(); }; public House createHouse() { return new AbstractFactryHouse.TileRoofedHouse(); }; } public static class DreamBFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Audi(); }; public House createHouse() { return new AbstractFactryHouse.CommodityHouse(); }; } public static class DreamCFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Tesla(); }; public House createHouse() { return new AbstractFactryHouse.Villa(); }; } }
測試類例如以下:
package com.open.design.factory; import com.open.design.factory.AbstractFactry.AbsDream; import com.open.design.factory.AbstractFactryCar.Car; import com.open.design.factory.AbstractFactryHouse.House; public class AbstractFactryTest { /** * @param args */ public static void main(String[] args) { AbsDream dream = new AbstractFactry.DreamAFactory(); Car car =dream.createCar(); House house=dream.createHouse(); car.printName(); house.printHouseName(); //------------------- dream = new AbstractFactry.DreamBFactory(); car =dream.createCar(); house=dream.createHouse(); car.printName(); house.printHouseName(); //------------------- dream = new AbstractFactry.DreamCFactory(); car =dream.createCar(); house=dream.createHouse(); car.printName(); house.printHouseName(); } }
打印結果例如以下:
長處與缺點:
抽象工廠模式面對的問題是多產品等級結構的系統設計。抽象工廠模式的每一個工廠創造出來的都是一族產品,而不是一個或者一組。
四、動態工廠
組成與簡單工廠類似。
詳細樣例:
抽象產品、詳細產品角色類定義例如以下:
package com.open.design.factory; public class DynamicFactoryData { //2.抽象產品角色:它通常是詳細產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。 public interface Car { void printName(); } //3.詳細產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個詳細類實現。public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }
工廠類定義例如以下:
package com.open.design.factory; import java.lang.reflect.Constructor; import com.open.design.factory.DynamicFactoryData.Car; public class DynamicFactory { public static Car produce(String carName) { ClassLoader mClassLoader=DynamicFactory.class.getClassLoader(); try { Class<?> mClass = mClassLoader.loadClass(carName); Constructor<?
>[] mConstructor=mClass.getConstructors(); return (Car) mConstructor[0].newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } }
測試類例如以下:
package com.open.design.factory; import com.open.design.factory.DynamicFactoryData.Car; public class DynamicFactoryTest { /** * @param args */ public static void main(String[] args) { Car car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Benz"); car.printName(); car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$BMW"); car.printName(); car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Audi"); car.printName(); car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Tesla"); car.printName(); } }
打印結果例如以下:
長處與缺點:
簡單模式的優化版,代碼簡潔。
總結:
(1)簡單工廠模式是由一個詳細的類去創建其它類的實例。
(對於添加新的產品。無能為力)
(2)工廠方法模式是有一個抽象的父類定義公共接口,子類負責生成詳細的對象,這樣做的目的是將類的實例化操作延遲到子類中完畢。
(支持添加新產品)
(3)抽象工廠模式提供一個創建一系列相關或相互依賴對象的接口。而無須指定他們詳細的類。它針對的是有多個產品的等級結構。而工廠方法模式針對的是一個產品的等級結構。
(對於添加新的產品,無能為力。支持添加產品族)
本文代碼地址:https://github.com/zz7zz7zz/design-pattern
參考博文:http://www.cnblogs.com/forlina/archive/2011/06/21/2086114.html
http://www.cnblogs.com/devinzhang/archive/2011/12/19/2293160.html
設計模式之工廠模式 (二)