「JavaScript设计模式」之创建型

194 阅读1分钟

工厂模式

关于工厂模式,我们首先设计一个以下的类结构:动物类、猫类、狗类,其中猫类和狗类继承于动物类。具体代码如下:

class Animal {
    constructor(name) {
        this.name = name
    }
}
class Cat extends Animal {
    constructor(name) {
        super(name)
    }
    meow() {
        console.log(`${this.name}:喵喵`)
    }
}
class Dog extends Animal {
    constructor(name) {
        super(name)
    }
    bark() {
        console.log(`${this.name}:汪汪`)
    }
}

设计思想:通过一个函数集中管理多个相同性质的子类的实例对象生成。

适用场景:工厂模式常用于具有层次性的类结构,管理它们子类的实例对象生成。

解决的问题:解决无法统一管理实例对象的生成的现象。

class ClassError extends Error {
    constructor(value) {
        super(`${value} not a subclass of Animail`)
        this.name = 'ClassError'
    }
}

// 设计思想:通过一个函数集中管理多个相同性质的子类的实例对象生成
class Factory {
    constructor(supClass, factoryName) {
        this.supClass = supClass
        this.factoryName = factoryName
    }
    create(subClass, value) {
        if (subClass.prototype instanceof this.supClass) {
            return new subClass(value)
        } else {
            throw new ClassError(subClass)
        }
    }
}

const AnimailFactory = new Factory(Animal, '动物工厂')
const catInstance = AnimailFactory.create(Cat, '泡芙')
const dogInstance = AnimailFactory.create(Dog, '旺财')
catInstance.meow()
dogInstance.bark()

单例模式

设计思想:一个类有且仅有一个实例对象,并且具备访问该实例对象的方法。

适用场景:仅有一个对象可在全局中提供访问,如常用的Axios、Jquery等工具库。

解决的问题:解决大量实例对象占用内存的现象。

ES6写法:通过静态变量缓存实例对象

class Singleton {
    static instance = null
    static createInstance() {
        if (!Singleton.instance) {
            Singleton.instance = new Singleton()
        }
        return Singleton.instance
    }
    constructor() { } // 构造函数
}

ES5写法:通过函数闭包缓存实例对象

function Singleton() { } // 构造函数
Singleton.createInstance = (function () {
    let instance = null
    return function () {
        if (!instance) {
            instance = new Singleton()
        }
        return instance
    }
})()

对象字面量写法:通过块级作用域缓存实例对象

const Singleton = {
    instance: null,
    constructor: function () { }, // 构造函数
    createInstance: function () {
        if (!this.instance) {
            this.instance = new this.constructor()
        }
        return this.instance
    }
}

const instanceA = Singleton.createInstance()
const instanceB = Singleton.createInstance()
console.log(instanceA === instanceB) // true