簡單工廠、工廠方法和抽象工廠的區別

工廠模式一般分爲簡單工廠、工廠方法和抽象工廠三種,看了很多資料,好多講的都是雲裏霧裏的。要麼是概念太多,讓人看得一臉懵逼,要麼是舉得例子不太恰當,看了更讓人迷惑了。經過自己一番研究,通過一個簡單的例子,終於搞明白了它們之間的區別。

下面以生產寶馬、奔馳汽車的工廠爲例,講解它們之間的區別。

一、簡單工廠模式

創建一個工廠類,根據傳入的參數來決定創建哪個汽車類

//汽車接口
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方法,新增一個大衆的分支。 再回憶一下,之前講過的軟件六大設計原則之一開閉原則。很明顯,這違背了開閉原則(對修改是關閉的)。

於是,有了下邊的工廠方法,可以保證遵循開閉原則。

二、工廠方法模式

工廠方法,相比於簡單工廠,多了一個角色——工廠接口,負責定義生產汽車的公共接口,然後每個工廠實現類都去實現這個接口。

//工廠接口
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接口就可以了。不需要修改原來的代碼,這就符合開閉原則了。

三、 抽象工廠模式

初識抽象工廠的同學,總是很迷惑它和工廠方法有什麼區別,不就是在工廠實現類裏多了幾個方法嗎。其實,抽象工廠是對工廠方法的升級,用於創建一組相互關聯或相互依賴的對象。

在此需要了解一下產品等級和產品族的關係。假如有一個汽車製造商,它只生產低配版的汽車產品(至於爲什麼,我猜是低配版更親民,銷量更高吧,哈哈),其中就包括低配寶馬和低配奔馳。還有一個汽車製造商只生產高配版的汽車(沒什麼原因,就是錢多任性,高端大氣上檔次),如高配寶馬和高配奔馳。

我們就把高配製造商或者低配製造商稱爲一個產品族。而其中的低配寶馬和低配奔馳屬於同一個產品等級,高配寶馬和高配奔馳屬於同一個產品等級。

畫一張圖來理解一下它們的概念,橫向是三個產品族,縱向是兩個產品等級。

file

代碼如下:

//工廠接口,包含兩個方法,創建寶馬和創建奔馳
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();  //低配奔馳車
    }
}

乍一看,抽象工廠和工廠方法特別的相似,其實這裏邊就是多了一個產品族的概念,它強調一個產品族的對象應該放到同一個工廠類裏邊。比如,我再需要一箇中配版或者豪華版的汽車製造商,只需要實現它的具體工廠類和相應的各同等級的汽車類。

總結:

  1. 簡單工廠顧明思議,實現比較簡單,只需要傳入一個特定參數即可,不用知道具體的工廠實現類名,缺點就是違背了開閉原則。
  2. 工廠方法和抽象工廠,遵守開閉原則,解耦了類關係。但是,擴展比較複雜,需要增加一系列的類。
  3. 需要注意,工廠方法和抽象工廠的區別就在於,抽象工廠關注於某一個產品族,當產品對象之間是有關聯關係的一個產品族時用這種方式,而工廠方法沒有產品族的概念。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章