Typescript 工廠模式

標籤: 前端 設計模式 工廠模式 typescript factory


如果下面的代碼你能輕易閱讀,那麼你已經熟悉工廠模式,可以接着學習其他的設計模式。

工廠模式:一個類或對象中往往會包含別的對象,在創建這種成員對象時。我們經常使用new來創建,但是這會導致相關的兩個類之間產生依賴性。工廠模式使用了一個方法來決定使用究竟實例哪個類。

簡單工廠

工廠模式,即類似於工廠一樣有一個流程化的形式。
比方說服裝廠,先是任意一種服裝的製作,然後是漂洗,最後是包裝出場。
寫成代碼如下所示。

/* simple-factory.ts */
import CloseTypeEnum from './close-type-enum';
class SimpleFactory {
    private static _instance: SimpleFactory;
    public static get instance() {
        if (!this._instance) {
            this._instance = new SimpleFactory();
        }
        return this._instance;
    }
    public createClose(closeType: CloseTypeEnum): string {
        let closeName: string = null;
        switch (closeType) {
            case CloseTypeEnum.Sweater:
                closeName = 'sweater';
                break;
            case CloseTypeEnum.Shirt:
                closeName = 'shirt';
                break;
            case CloseTypeEnum.Jacket:
                closeName = 'jacket';
                break;
            default :
                throw new Error('can\'t find type' + closeType);
        }
        this.washingsClose(closeName);
        this.packagingClose(closeName);
        return closeName;
    }
    public washingsClose(close: string) {}
    public packagingClose(close: string) {}
}

用一個類來創建經過一系列流程對象,對象的創建和流程解除依賴。從而解除依賴,更容易增加對象種類。便於以後維護和擴展。

抽象工廠

如上面的服裝廠的流程,我們的服裝廠要增加一種衣服的類型時,仍然需要進入工廠類中增加一個case。如果每一個case裏面的流程是非常複雜的,那我們用switch case顯然是不合適的。
這時候我們需要用到抽象工廠
將生產衣服的這個switch case抽象成一個接口,因爲我們只關心最終造出來的衣服,而不關心製作的流程。
換成代碼就是寫幾個方法都去實現makeClose的接口。

/* i-factory-interface.ts */
interface ICloseMakerFactory {
    makeClose(): IClose
}
interface IClose {
    name: string
    price: number
    note: string
}
export {
    ICloseMakerFactory,
    IClose,
};
/* sweater-producer.ts */
import { IClose, ICloseMakerFactory } from '../i-factory-interface';
export default class SweaterProducer implements ICloseMakerFactory {
    makeClose(): IClose {
        return {
            name: 'sweater',
            price: 15,
            note: 'The process can be complex',
        };
    }
}
/* shirt-producer.ts */
import { IClose, ICloseMakerFactory } from '../i-factory-interface';
export default class ShirtProducer implements ICloseMakerFactory {
    makeClose(): IClose {
        return {
            name: 'shirt',
            price: 20,
            note: 'The process can be complex',
        };
    }
}
**/* jacket-producer.ts */
import { IClose, ICloseMakerFactory } from '../i-factory-interface';
export default class JacketProducer implements ICloseMakerFactory {
    makeClose(): IClose {
        return {
            name: 'jacket',
            price: 25,
            note: 'The process can be complex',
        };
    }
}**

然後在主方法中調用這些方法去實現生產衣服的過程。

class AbstractFactory {
    private static _instance: AbstractFactory;
    private closeTypeAnalyzerMapping: Map<CloseTypeEnum, ICloseMakerFactory>;
    constructor() {
        this.closeTypeAnalyzerMapping.set(CloseTypeEnum.Jacket, new JacketProducer());
        this.closeTypeAnalyzerMapping.set(CloseTypeEnum.Shirt, new ShirtProducer());
        this.closeTypeAnalyzerMapping.set(CloseTypeEnum.Sweater, new SweaterProducer());
    }
    public static get instance() {
        if (!this._instance) {
            this._instance = new AbstractFactory();
        }
        return this._instance;
    }
    public makeCloseTypeAnalyzer(type: CloseTypeEnum): ICloseMakerFactory {
        if (this.closeTypeAnalyzerMapping.has(type)) {
            return this.closeTypeAnalyzerMapping.get(type);
        } else {
            throw new Error('our factory don\'t have this type');
        }
    }
}
const shrit= AbstractFactory.instance.makeCloseTypeAnalyzer(CloseTypeEnum.Shirt).makeClose();

當然,實際場景中過程的每一步都會根據衣服的種類有多種實現方法,我們可以按照生產衣服一樣將他們區分開來。
這樣,未來我們增加了一種衣服的類型或者洗滌方法等,只需要增加一個實現類而不用大面積的改變主方法。

工廠模式的利弊

利:

  • 消除對象間的耦合:
    使用工廠方法而不是new關鍵字,解除創建過程中的耦合步驟,增加可維護性和可測試性。
  • 易於模塊化
    使用工廠模式,可以先創建一個抽象的父類,然後在子類中創建工廠方法,從而把成員對象的實例化推遲到更專門的子類中進行。增加可拓展性。

弊:
工廠模式在處理多流程或者是根據上下文創建實例的情況下非常好用。但是在單一流程或者是不需要根據上下文創建對象的情況下使用反而會增加閱讀成本。

所以我們應該在恰當的場景中使用工廠模式。如果拿不定主意,那就不要使用,因爲在以後的重構中還有機會使用工廠模式。

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