工廠模式的一些思考和總結

工廠模式Factory Pattern簡介

工廠模式(Factory Pattern)是日常開發過程中使用頻率較高的一種設計模式。工廠模式屬於設計模式三大類(創建型模式(Creational Patterns)、結構型模式(Structural Patterns)、行爲型模式(Behavioral Patterns))中的創建型模式(Creational Patterns),它簡化了調用方創建對象的方式。工廠模式基本上會被分爲三種——簡單工廠模式、工廠方式模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式(Simple Factory pattern):由一個工廠對象決定創建哪一種產品的實例。

簡單工廠一般用在創建產品不多,一個工廠即可完成,下面代碼描述了汽車的簡單工廠模式的基本實現思路。

定義汽車ICar接口:

public interface ICar {
    /**
     * 汽車啓動
     */
    void run();
}

具體汽車:

public class MPVCar implements ICar {
    @Override
    public void run() {
        System.out.println("MPV car is running!");
    }
}

public class SedanCar implements ICar {
    @Override
    public void run() {
        System.out.println("Sedan car is running!");
    }
}

public class SUVCar implements ICar{
    @Override
    public void run() {
        System.out.println("SUV car is running!");
    }
}

工廠類:

public class CarFactory {
    public static ICar create(String model) {
        ICar iCar = null;
        if ("sedan".equalsIgnoreCase(model)) {
            iCar = new SedanCar();
        } else if ("suv".equalsIgnoreCase(model)) {
            iCar = new SUVCar();
        } else if ("mpv".equalsIgnoreCase(model)) {
            iCar = new MPVCar();
        }
        return iCar;
    }
}

通過調用工廠類,創建汽車對象:

public class CarMain {
    public static void main(String[] args) {
        ICar car = CarFactory.create("sedan");
        car.run();
    }
}

執行結果:

Sedan car is running!

通過以上代碼示例描述,會發現簡單工廠模式有以下特點:

  1. 適用用產品較少的場景(如產品太多,Factory將很難維護,不利於擴展)
  2. 隱藏了創建對象的具體細節,調用方不用關注如何創建了對象,只用關心調用方自己的業務細節。

簡單工廠模式的缺點也很明顯:上面已經提到,單一工廠需要維護過多的產品,增加一個產品需要升級一次工廠,增加了未來的改造成本,違背了設計原則的開閉原則(對擴展開放,對修改關閉)。

工廠方法模式(Factory Method Pattern)

工廠方法模式(Factory Method Pattern):定義一個創建對象的接口,讓其實現這個接口的方法決定創建哪個對象,將產品對象的的創建工作推遲到子類中進行。

工廠方法模式,是對簡單工廠模式的改進,對簡單工廠的進一步抽象化。好處是可在不修改原有代碼的基礎上引進新的產品,實現開閉原則的對擴展開放,對修改關閉。

改進後的工廠方法,創建的對象工廠接口如下:

public interface IFactory {
    /**
     * 創建方法
     * @return
     */
    ICar create();
}

具體實現工廠:

public class SedanFactory implements IFactory {
    @Override
    public ICar create() {
        return new SedanCar();
    }
}

public class SUVFactory implements IFactory {
    @Override
    public ICar create() {
        return new SUVCar();
    }
}

public class MPVFactory implements IFactory {
    @Override
    public ICar create() {
        return new MPVCar();
    }
}

調用工廠類:

public class CarMain {
    public static void main(String[] args) {
        IFactory sedanFactory = new SedanFactory();
        ICar car = sedanFactory.create();
        car.run();
    }
}

運行測試結果:

Sedan car is running!

工廠方法模式適用用於以下場景:

  1. 創建對象需要大量重複的代碼。
  2. 調用方不關心創建對象的細節。
  3. 類通過其子類指定創建具體對象。

同時工廠方法也有缺點:

  1. 工廠類容易過多,增加複雜度。

抽象工廠模式(Abstract Factory Pattern)

抽象工廠模式(Abstract Factory Pattern): 是一種爲訪問類提供一個創建一組相關或相互依賴對象的接口,且訪問類無須指定所要產品的具體類就能得到同族的不同等級的產品的模式結構。

需要一個對象類庫,所有的對象通過同樣的接口出現,從而使調用放不依賴具體實現。比如汽車工廠分很多品牌,這些品牌有奔馳、寶馬、奧迪等,每個工廠都能生產很多型號車輛,但是他們不可能使用一個工廠生產汽車。所以需第一個奔馳工廠、一個寶馬工廠、一個奧迪工廠用於生產各自品牌的不同型號的汽車。
用代碼實現則如下定義工廠接口:

public interface IFactory {
    /**
     * 創建轎車
     *
     * @return
     */
    ICar createSedanCar();

    /**
     * 創建SUV
     *
     * @return
     */
    ICar createSUVCar();

    /**
     * 創建MVP
     *
     * @return
     */
    ICar createMPVCar();
}

實現一個奔馳工廠:

public class BenzFactory implements IFactory{
    @Override
    public ICar createSedanCar() {
        return new SedanCar();
    }

    @Override
    public ICar createSUVCar() {
        return new SUVCar();
    }

    @Override
    public ICar createMPVCar() {
        return new MPVCar();
    }
}

調用工廠類:

public class CarMain {
    public static void main(String[] args) {
        IFactory sedanFactory = new BenzFactory();
        ICar car = sedanFactory.createSedanCar();
        car.run();
    }
}

運行結果:

Sedan car is running!

抽象工廠模式有如下特點:

  1. 抽象工廠很方便的描述了多等級產品。
  2. 可以在類的內部對相關聯的多等級產品進行管理。
  3. 當只有一個對象需要被創建時,抽象工廠模式其實就變成了工廠方法模式

缺點:

  1. 當需要增加一個對象產品時,所有工廠都要進行修

總結

工廠模式的應用,爲了方便優雅的創建對象,同時調用方不需要過分關注創建細節,同時隔離了因爲對象改變時,調用方的過多改動。但是工廠模式的一些缺點也是需要能夠容忍的,沒有絕對的原則不可被打破且萬能的。

發佈了7 篇原創文章 · 獲贊 4 · 訪問量 8654
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章