工廠模式通常分爲簡單工廠、工廠方法和抽象工廠三種,看了不少資料,好多講的都是雲裏霧裏的。要麼是概念太多,讓人看得一臉懵逼,要麼是舉得例子不太恰當,看了更讓人迷惑了。通過本身一番研究,經過一個簡單的例子,終於搞明白了它們之間的區別。ide
下面以生產寶馬、奔馳汽車的工廠爲例,講解它們之間的區別。設計
1、簡單工廠模式code
建立一個工廠類,根據傳入的參數來決定建立哪一個汽車類對象
//汽車接口 public interface Car { void getCar(); } //寶馬汽車類 public class BMWCar implements Car { @Override public void getCar() { System.out.println("這是寶馬車"); } } //奔馳汽車類 public class BenzCar implements Car { @Override public void getCar() { System.out.println("這是奔馳車"); } } //工廠類,用於決定建立哪個具體的汽車類 public class DefaultFactory { public Car produce(String name){ if(name.equals("benz")){ return new BenzCar(); }else if(name.equals("bmw")){ return new BMWCar(); } return null; } } public class FTest { public static void main(String[] args) { DefaultFactory factory = new DefaultFactory(); Car car = factory.produce("bmw"); car.getCar(); //這是寶馬車 Car benz = factory.produce("benz"); benz.getCar(); //這是奔馳車 } }
能夠看到,在具體的工廠類DefaultFactory中,咱們根據傳入的name來決定建立哪個汽車類。當須要建立寶馬時,傳入bmw,當須要建立奔馳時傳入benz。思考一下,若是我須要建立一個大衆汽車呢。是否是須要建立一個大衆汽車類實現Car接口,還須要修改工廠類的produce方法,新增一個大衆的分支。 再回憶一下,以前講過的軟件六大設計原則之一開閉原則。很明顯,這違背了開閉原則(對修改是關閉的)。blog
因而,有了下邊的工廠方法,能夠保證遵循開閉原則。接口
2、工廠方法模式get
工廠方法,相比於簡單工廠,多了一個角色——工廠接口,負責定義生產汽車的公共接口,而後每一個工廠實現類都去實現這個接口。產品
//工廠接口 public interface IFactory { Car produce(); } //寶馬生產工廠 public class BMWFactory implements IFactory{ @Override public Car produce() { return new BMWCar(); } } //奔馳生產工廠 public class BenzFactory implements IFactory { @Override public Car produce() { return new BenzCar(); } } public class FacTest { public static void main(String[] args) { BMWFactory bmwFactory = new BMWFactory(); bmwFactory.produce().getCar(); //這是寶馬車 BenzFactory benzFactory = new BenzFactory(); benzFactory.produce().getCar(); //這是奔馳車 } }
能夠看到,我把以前的一個工廠,拆分爲兩個工廠。當具體須要哪一個汽車的時候,就去實例化它對應的工廠。這樣,當再須要大衆車的時候,我只須要添加一個大衆車的類和大衆車對應的工廠實現類去實現IFactory接口就能夠了。不須要修改原來的代碼,這就符合開閉原則了。class
3、 抽象工廠模式擴展
初識抽象工廠的同窗,老是很迷惑它和工廠方法有什麼區別,不就是在工廠實現類裏多了幾個方法嗎。其實,抽象工廠是對工廠方法的升級,用於建立一組相互關聯或相互依賴的對象。
在此須要瞭解一下產品等級和產品族的關係。假若有一個汽車製造商,它只生產低配版的汽車產品(至於爲何,我猜是低配版更親民,銷量更高吧,哈哈),其中就包括低配寶馬和低配奔馳。還有一個汽車製造商只生產高配版的汽車(沒什麼緣由,就是錢多任性,高端大氣上檔次),如高配寶馬和高配奔馳。
咱們就把高配製造商或者低配製造商稱爲一個產品族。而其中的低配寶馬和低配奔馳屬於同一個產品等級,高配寶馬和高配奔馳屬於同一個產品等級。
畫一張圖來理解一下它們的概念,橫向是三個產品族,縱向是兩個產品等級。
代碼以下:
//工廠接口,包含兩個方法,建立寶馬和建立奔馳 public interface IFactory { Car produceBMW(); Car produceBenz(); } //-------- 高配車和工廠實現類 -------// public class HighBMW implements Car { @Override public void getCar() { System.out.println("高配寶馬車"); } } public class HighBenz implements Car { @Override public void getCar() { System.out.println("高配奔馳車"); } } public class HighFactory implements IFactory { @Override public Car produceBMW() { return new HighBMW(); } @Override public Car produceBenz() { return new HighBenz(); } } //-------- 低配車和工廠實現類 ----------// public class LowBMW implements Car { @Override public void getCar() { System.out.println("低配寶馬車"); } } public class LowBenz implements Car { @Override public void getCar() { System.out.printf("低配奔馳車"); } } public class LowFactory implements IFactory { @Override public Car produceBMW() { return new LowBMW(); } @Override public Car produceBenz() { return new LowBenz(); } } public class AbsTest { public static void main(String[] args) { HighFactory highFactory = new HighFactory(); highFactory.produceBMW().getCar(); //高配寶馬車 highFactory.produceBenz().getCar(); //高配奔馳車 LowFactory lowFactory = new LowFactory(); lowFactory.produceBMW().getCar(); //低配寶馬車 lowFactory.produceBenz().getCar(); //低配奔馳車 } }
乍一看,抽象工廠和工廠方法特別的類似,其實這裏邊就是多了一個產品族的概念,它強調一個產品族的對象應該放到同一個工廠類裏邊。好比,我再須要一箇中配版或者豪華版的汽車製造商,只須要實現它的具體工廠類和相應的各同等級的汽車類。
總結: