設計模式-工廠模式和抽象工廠-Factory

摘抄至https://www.jianshu.com/p/3c3f6c95d7e7
本文講解GOF-23種設計模式其中的工廠方法模式抽象工廠模式
由於本人愛國情懷高漲,所以本文都以長安汽車作爲示例,閱讀本文需要對長安汽車有一定了解。
長安悅翔V7:長安旗下一款性價比超高的緊湊型家用轎車,輪胎尺寸R15。
長安CS75:長安旗下一款中端緊湊型城市SUV,輪胎尺寸R17。
以上兩款車和車輪胎都是長安集團的產品,那麼生產輪胎和組裝車的地方是長安的工廠。

一. 簡單工廠模式

1、簡介

簡單工廠模式(Simple Factory)其實不算是23種設計模式之一,只算是工廠方法模式的一種特殊寫法,是較爲常用的工廠模式(下文簡稱模式A)。

2、成員

抽象產品:它是具體產品的抽象父類 或者實現的接口。
具體產品:具體的產品類,在JAVA中是一個實現了抽象產品的類。
工廠類:生產具體產品的工廠,具有一定的業務邏輯和判斷,生產不同的具體產品

3、使用場景

在業務簡單,對象較少且不易改動的情況下可使用此模式。

4、代碼示例
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是一個長安汽車抽象類,用[abstract]抽象類也可實現!
 */
public interface ICar {

    /**
     * 汽車的價格
     */
    double getPrice();

    /**
     * 汽車的型號
     */
    String getModel();
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是具體的長安汽車產品-悅翔V7,需要實現汽車接口。
 */
public class V7Info implements ICar {

    @Override
    public double getPrice() {
        return 100000;
    }

    @Override
    public String getModel() {
        return "長安悅翔V7";
    }
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是具體的長安汽車產品-CS75,需要實現汽車接口。
 */
public class CS75Info implements ICar {

    @Override
    public double getPrice() {
        return 150000;
    }

    @Override
    public String getModel() {
        return "長安CS75";
    }
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 工廠模式-簡單模式
 * 解釋: 這是長安汽車的工廠,可以根據不同的需求生產不同的汽車產品。
 */
public class ICarFactory_1 {

    public static final String car_type_v7 = "V7";
    public static final String car_type_cs75 = "CS75";

    public static ICar createCar(String carType) {
        if (car_type_v7.equals(carType)) {
            return new V7Info();
        } else if (car_type_cs75.equals(carType)) {
            return new CS75Info();
        } else {
            return new V7Info();
        }
    }
}
 /**
     * 測試簡單工廠模式
     */
    public void TestFactory1() {
        ICar car1 = ICarFactory_1.createCar(ICarFactory_1.car_type_v7);
        Log.d("MainActivity", car1.getModel() + "的價格是" + car1.getPrice());
    }

最終打印結果:長安悅翔V7的價格是100000.0

二、工廠方法模式

1、簡介

工廠方法模式(Factory Method),是爲解決模式A的一些缺點而生。
(下文把此模式簡稱模式B)

2、優點/區別

1、解耦:消費者與產品完全隔離,消費者依賴產品接口實現對產品的操作。
2、擴展:如果要新增汽車類型,只需增加具體汽車類和工廠即可,不用修改原工廠。

3、成員:

除了模式A裏面的【抽象產品】【具體產品】,還需新增以下成員:
抽象工廠:它是具體工廠的抽象父類/實現的接口。
具體工廠:此處的工廠也是模式A中的工廠,與模式A工廠的區別是:模式A的工廠可以根據邏輯判斷生產不同的產品,而模式B的工廠只能生產一種產品,如果需要生產多種產品則需要創建多個工廠。

4、使用場景

如果產品類型比較單一,且不能預見需要創建哪些類、創建多少類的情況下使用模式B。

5、代碼示例:(接上文的例子)
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 工廠方法模式-長安的工廠都必須遵循此協議
 */
public interface ICarFactory_2 {
    ICar createCar();
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是長安其中一家工廠,此工廠只生產悅翔V7
 */
public class CarV7Factory_2 implements ICarFactory_2 {

    @Override
    public ICar createCar() {
        return new V7Info();
    }
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是長安另一家工廠,此工廠只生產CS75
 */
public class CarCS75Factory_2 implements ICarFactory_2 {

    @Override
    public ICar createCar() {
        return new CS75Info();
    }
}
     /**
     * 測試工廠方法模式
     */
    public void TestFactory2() {
        ICarFactory_2 factory_v7 = new CarV7Factory_2();
        ICar car_v7 = factory_v7.createCar();
        Log.d("MainActivity", "A:" + car_v7.getModel() + "的價格是" + car_v7.getPrice());

        ICarFactory_2 factory_CS75 = new CarCS75Factory_2();
        ICar car_75 = factory_CS75.createCar();
        Log.d("MainActivity", "B:" + car_75.getModel() + "的價格是" + car_75.getPrice());
    }

最終打印結果:
A:長安悅翔V7的價格是100000.0
B:長安CS75的價格是150000.0

三、抽象工廠模式

1、簡介

抽象工廠模式(Abstract Factory)是模式B的更爲抽象的寫法,成員與模式B相同,就不具體列舉了(以下簡稱模式C)。

2、代碼示例(繼續接上文例子,注意此例子中長安集團產品族中增加了新的產品:輪胎)
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是長安輪胎產品協議,用[abstract]抽象類也可實現!
 */
public interface ITyre {

    /**
     * 輪胎尺寸
     */
    String getSize();
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 長安悅翔V7的輪胎
 */
public class V7TyreInfo implements ITyre {

    @Override
    public String getSize() {
        return "R15";
    }
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 長安CS75的輪胎
 */
public class CS75TyreInfo implements ITyre {

    @Override
    public String getSize() {
        return "R17";
    }
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 抽象工廠模式
 * 解釋: 長安新增了產品,那麼工廠的協議就要改變了,既要生產汽車也要生產輪胎
 */
public interface ICarFactory_3 {

    /**
     * 生產汽車
     */
    ICar createCar();

    /**
     * 生產輪胎
     */
    ITyre createTyre();
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是長安其中一家工廠,此工廠原來只生產悅翔V7,現在新增了輪胎生產線
 */
public class CarV7Factiry_3 implements ICarFactory_3 {

    @Override
    public ICar createCar() {
        return new V7Info();
    }

    @Override
    public ITyre createTyre() {
        return new V7TyreInfo();
    }
}
/**
 * 作者: Created by AdminFun
 * 郵箱: [email protected]
 * 描述: 這是長安另一家工廠,此工廠原來只生產CS75,現在新增了CS75輪胎的生產線
 */
public class CarCS75Factory_3 implements ICarFactory_3 {
    @Override
    public ICar createCar() {
        return new CS75Info();
    }

    @Override
    public ITyre createTyre() {
        return new CS75TyreInfo();
    }
}
 /**
     * 測試抽象工廠模式
     */
    public void TestFactoiry3() {
        ICarFactory_3 factory_v7 = new CarV7Factiry_3();
        ICar carV7 = factory_v7.createCar();
        ITyre tyrev7 = factory_v7.createTyre();
        Log.d("MainActivity", "C:" + carV7.getModel() + "的價格是" + carV7.getPrice() + ",輪胎尺寸是" + tyrev7.getSize());

        ICarFactory_3 factory_75 = new CarCS75Factory_3();
        ICar car75 = factory_75.createCar();
        ITyre tyre75 = factory_75.createTyre();
        Log.d("MainActivity", "C:" + car75.getModel() + "的價格是" + car75.getPrice() + ",輪胎尺寸是" + tyre75.getSize());
    }

最終打印結果:
C:長安悅翔V7的價格是100000.0,輪胎尺寸是R15
C:長安CS75的價格是150000.0,輪胎尺寸是R17

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章