一天一个设计模式之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

相关文章
相关标签/搜索