愿你坚持不懈,努力进步,进阶成自己理想的人

—— 2017.09, 写给3年后的自己

每天一个JavaScript设计模式:抽象工厂模式

一、场景

抽象工厂模式是一种创建型模式,抽象工厂模式创建的是类簇,而非是具体某一个的实例。
抽象工厂模式适用于系统里有多于一个的产品族,而只需要用到某一族的场景


二、核心思想

抽象工厂模式里,工厂是一个抽象类,它不能够直接被实例化,工厂的作用是制定产品族类的结构,
示例如下:

// 抽象工厂方法
function VehicleFactory(subType, superType) {
    if (typeof VehicleFactory[superType] === 'function') {
        function F() {}
        F.prototype = new VehicleFactory[superType]()
        subType.constructor = subType
        subType.prototype = new F()
    } else {
        throw new Error('未创建该抽象类')
    }
}

/* 定义抽象类的结构 */
// 汽车抽象类
VehicleFactory.Car = function() {
    this.type = 'car'
}
VehicleFactory.Car.prototype = {
    getPrice() {
        return new Error('抽象方法不能调用')
    },
    getSpeed() {
        return new Error('抽象方法不能调用')
    }
}

// 公交车抽象类
VehicleFactory.Bus = function() {
    this.type = 'bus'
}
VehicleFactory.Bus.prototype = {
    getPrice() {
        return new Error('抽象方法不能调用')
    },
    getPassengerNum() {
        return new Error('抽象方法不能调用')
    }
}

// 货车抽象类
VehicleFactory.Truck = function() {
    this.type = 'truck'
}
VehicleFactory.Truck.prototype = {
    getPrice() {
        return new Error('抽象方法不能调用')
    },
    getTrainload() {
        return new Error('抽象方法不能调用')
    }
}

实现具体的类则如下:

// 汽车:宝马具体类
function BMW(price, speed) {
    this.price = price
    this.speed = speed
}
VehicleFactory(BMW, 'Car')
BMW.prototype.getPrice = function() {
    return this.price
}
BMW.prototype.getSpeed = function() {
    return this.speed
}

当需要生产实例时,则:

const bmw530 = new BMW(500000, 250)
bmw530.getPrice() // 500000
bmw530.getSpeed() // 250
bmw530.type // 'Car'