屬於建立型設計模式,須要生成的對象叫作產品 ,生成對象的地方叫作工廠 。java
使用場景:在任何須要生成複雜對象的地方,均可以使用工廠方法模式。
直接用new能夠完成的不須要用工廠模式程序員
一個栗子:
我喜歡吃麪條,抽象一個麪條基類,(接口也能夠),這是產品的抽象類。設計模式
public abstract class INoodles { /** * 描述每種麪條啥樣的 */ public abstract void desc(); }
先來一份蘭州拉麪(具體的產品類):ide
public class LzNoodles extends INoodles { @Override public void desc() { System.out.println("蘭州拉麪 上海的好貴 家裏才5 6塊錢一碗"); } }
程序員加班必備也要吃泡麪(具體的產品類):測試
public class PaoNoodles extends INoodles { @Override public void desc() { System.out.println("泡麪好吃 可不要貪杯"); } }
還有我最愛吃的家鄉的幹扣面(具體的產品類):spa
public class GankouNoodles extends INoodles { @Override public void desc() { System.out.println("仍是家裏的幹扣面好吃 6塊一碗"); } }
準備工做作完了,咱們來到一家「簡單面館」(簡單工廠類),菜單以下:設計
public class SimpleNoodlesFactory { public static final int TYPE_LZ = 1;//蘭州拉麪 public static final int TYPE_PM = 2;//泡麪 public static final int TYPE_GK = 3;//幹扣面 public static INoodles createNoodles(int type) { switch (type) { case TYPE_LZ: return new LzNoodles(); case TYPE_PM: return new PaoNoodles(); case TYPE_GK: default: return new GankouNoodles(); } } }
簡單面館就提供三種麪條(產品),你說你要啥,他就給你啥。這裏我點了一份幹扣面:code
/** * 簡單工廠模式 */ INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK); noodles.desc();
輸出:對象
仍是家裏的幹扣面好吃 6塊一碗
1 它是一個具體的類,非接口 抽象類。有一個重要的create()方法,利用if或者 switch建立產品並返回。接口
2 create()方法一般是靜態的,因此也稱之爲靜態工廠。
1 擴展性差(我想增長一種麪條,除了新增一個麪條產品類,還須要修改工廠類方法)
2 不一樣的產品須要不一樣額外參數的時候 不支持。
public class SimpleFactory { public Object create(Class<?> clazz) { if (clazz.getName().equals(Plane.class.getName())) { return createPlane(); } else if (clazz.getName().equals(Broom.class.getName())) { return createBroom(); } return null; } private Broom createBroom() { return new Broom(); } private Plane createPlane() { return new Plane(); } }
測試代碼:
public class FactoryTest { public static void main(String[] args) { // 簡單工廠模式測試 SimpleFactory simpleFactory = new SimpleFactory(); Broom broom = (Broom) simpleFactory.create(Broom.class); broom.run(); } }
咱們來看一下工廠方法模式的定義吧。工廠方法模式定義了一個建立對象的接口,但由子類決定要實例化哪個。工廠方法讓類把實例化推遲到了子類。(定義摘自《Head First設計模式》)
抽象工廠
public abstract class VehicleFactory { public abstract Moveable create(); }
具體工廠
public class BroomFactory extends VehicleFactory { @Override public Moveable create() { return new Broom(); } }
抽象產品
public interface Moveable { public void run(); }
具體產品
public class Broom implements Moveable { @Override public void run() { System.out.println("我是Broom.我在飛..."); } }
測試代碼
VehicleFactory factory = new BroomFactory(); Moveable moveable = factory.create(); moveable.run();
從上面的工廠方法中的結構圖中,咱們能夠看到其中的具體工廠A和B是兩個徹底獨立的。二者除了都是抽象工廠的子類,沒有任何其餘的交集。
可是,若是咱們有這樣一個需求:具體工廠A和B須要生產一些同類型的不一樣產品。那麼咱們就能夠試試抽象工廠模式。
咱們來看看抽象工廠模式是怎麼定義的:爲建立一組相關或相互依賴的對象提供一個接口,並且無需指定他們的具體類。一樣在下面的結構圖中,咱們能夠更好地解釋這必定義。咱們的抽象工廠中包含一系列的去構造一個抽象產品的方法,而具體產品的實現則是放在了具體工廠(圖中的A和B)中進行。
抽象工廠:
public abstract class AbstractFactory { public abstract Flyable createFlyable(); public abstract Moveable createMoveable(); public abstract Writeable createWriteable(); }
具體工廠
public class Factory1 extends AbstractFactory { @Override public Flyable createFlyable() { return new Aircraft(); } @Override public Moveable createMoveable() { return new Car(); } @Override public Writeable createWriteable() { return new Pen(); } }
抽象產品接口
public interface Flyable { public void fly(int height); }
具體產品
public class Aircraft implements Flyable { @Override public void fly(int height) { System.out.println("我是一架客運機,我目前的飛行高度爲:" + height + "公里。"); } }
測試代碼
public class FactoryTest { public static void main(String[] args) { AbstractFactory factory = new Factory1(); Flyable flyable = factory.createFlyable(); flyable.fly(1589); Moveable moveable = factory.createMoveable(); moveable.run(87.6); Writeable writeable = factory.createWriteable(); writeable.write("Hello World."); } }
以上就是工廠模式的基本實現和詳細說明。包括了簡單工廠模式、工廠方法模式、抽象工廠模式。咱們能夠基於需求來選擇合適的工廠模式