一天一個設計模式之JS實現——工廠模式

參考文章:
深刻理解java三種工廠模式
工廠模式,工廠方法模式,抽象工廠模式 詳解java

工廠模式(Factory Pattern)是 Java 中最經常使用的設計模式之一。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。
在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而且是經過使用一個共同的接口來指向新建立的對象。設計模式

工廠模式根據工廠抽象級別分爲三種:
一、簡單工廠模式
二、工廠方法模式
三、抽象工廠模式函數

工廠模式的角色通常有如下幾個:
一、抽象工廠類(注:簡單工廠無此類)
二、具體工廠類
三、抽象產品類
四、具體產品類this

簡單工廠模式

class BMW {
    drive() {
        console.log('drive bmw...');
    }
}
class Benz {
    drive() {
        console.log('drive Benz...');
    }
}
class Factory {
    getBMWCar() {
        return new BMW();
    }
    getBenzCar() {
        return new Benz();
    }
}

var f1 = new Factory();
f1.getBMWCar().drive();
f1.getBenzCar().drive();

當須要添加一類產品時,須要在工廠裏添加對應的生產邏輯,違背了開閉原則,簡單工廠模式只在很是簡單的狀況下使用。.net

工廠方法模式

因爲簡單工廠的弊端明顯,更多時候使用到的是工廠方法模式,工廠方法模式把生產過程下放到派生類,因此當添加一類產品的時候只需添加一個工廠,擴展性加強。prototype

注:因爲JS沒有接口也沒有抽象類的說法,用如下的形式模擬。設計

class FactoryInterface {
    constructor() {
        if (Object.getPrototypeOf(this) === FactoryInterface.prototype) {
            throw new Error('該類是抽象類,沒法實例化')
        }
    }
    getCar() {
        throw new Error('派生類必須實現該方法,抽象函數沒法直接調用!');
    }
}   
class BMWFactory extends FactoryInterface {
    getCar() {
        return new BMW();
    }
}
class BenzFactory extends FactoryInterface {
    getCar() {
        return new Benz();
    }
}
var bmwF = new BMWFactory();
var benzF = new BenzFactory();
bmwF.getCar().drive();
benzF.getCar().drive();

抽象工廠模式

抽象工廠模式的用意爲:給客戶端提供一個接口,能夠建立多個產品族中的產品對象。並且使用抽象工廠模式還要知足如下條件:
1.系統中有多個產品族,而系統一次只可能消費其中一族產品
2.同屬於同一個產品族的產品以其使用。
舉個例子,寶馬和奔馳兩個牌子都有越野車和商務車,寶馬系的是一個產品族,奔馳系的也是一個產品族,每一個產品族下面都有相相似的產品。code

class SportsCar {
    constructor() {
        if (Object.getPrototypeOf(this) === SportsCar.prototype) {
            throw new Error('該類是抽象類,沒法實例化')
        }
    }
    crossCountry() {
        throw new Error('派生類必須實現該方法,抽象函數沒法直接調用!');
    }
}
class BussinessCar {
    constructor() {
        if (Object.getPrototypeOf(this) === BussinessCar.prototype) {
            throw new Error('該類是抽象類,沒法實例化')
        }
    }
    talkBusiness() {
        throw new Error('派生類必須實現該方法,抽象函數沒法直接調用!');
    }
}
class BMWSportsCar extends SportsCar {
    crossCountry() {
        console.log('寶馬去越野');
    }
}
class BenzSportsCar extends SportsCar {
    crossCountry() {
        console.log('奔馳去越野');
    }
}
class BMWBussinessCar extends BussinessCar {
    talkBusiness() {
        console.log('寶馬去談生意');
    }
}
class BenzBussinessCar extends BussinessCar {
    talkBusiness() {
        console.log('奔馳去談生意');
    }
}
class AbstractFactory {
    constructor() {
        if (Object.getPrototypeOf(this) === AbstractFactory.prototype) {
            throw new Error('該類是抽象類,沒法實例化')
        }
    }
    getSportsCar() {
        throw new Error('派生類必須實現該方法,抽象函數沒法直接調用!');
    }
    getBussinessCar() {
        throw new Error('派生類必須實現該方法,抽象函數沒法直接調用!');
    }
}

class BMWSoleFactory extends AbstractFactory {
    getSportsCar() {
        return new BMWSportsCar();
    }
    getBussinessCar() {
        return new BMWBussinessCar();
    }
}
class BenzSoleFactory extends AbstractFactory {
    getSportsCar() {
        return new BenzSportsCar();
    }
    getBussinessCar() {
        return new BenzBussinessCar();
    }
}

var benf2 = new BenzSoleFactory();
var bmwf2 = new BMWSoleFactory();
benf2.getSportsCar().crossCountry();
benf2.getBussinessCar().talkBusiness();
bmwf2.getSportsCar().crossCountry();
bmwf2.getBussinessCar().talkBusiness();

小結:
工廠模式的做用是解耦了產品的生產和使用部分,讓使用須要的產品的時候只須要調用對應的接口便可,減小冗餘代碼。
優勢:一、隱藏了生產過程,只需調用相應接口;二、擴展性好,當須要添加一類產品時,只需添加對應工廠類便可。
與建造者模式區別:工廠模式不須要客戶端關心構建過程,只須要了解產品對應的工廠便可;建造者模式更多的是構建擁有複雜的內部結構的對象,過程由Derector控制。htm

相關文章
相關標籤/搜索