工厂模式(Factory Pattern)

我们试想一下,我们想创建一个复杂的对象,创建前需要做一二三四五六步,并且在业务中需要频繁进行对象创建。那么,选工厂模式就对了。一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型。

我们来看下代码:

function createVehicle(type) {
    let context;
    switch(type) {
        case 'dog':
            return new Dog(context);
        case 'cat':
            return new Cat(context);
        case 'duck':
            return new Duck(context);
    }
}
复制代码

适用场景

  • 当我们的对象或者组件设置涉及到高程度级别的复杂度时。
  • 当我们需要根据我们所在的环境方便的生成不同对象的实体时。
  • 当我们在许多共享同一个属性的许多小型对象或组件上工作时。
  • 当带有其它仅仅需要满足一种API约定(又名鸭式类型)的对象的组合对象工作时.这对于解耦来说是有用的。

不适用场景

  • 对象创建过程比较简单,过度的抽象不利于后期的维护迭代

抽象工厂模式(Abstract Factory Pattern)

可以简单理解为工厂的工厂。它的目标是以一个通用的目标将一组独立的工厂进行封装,它将一堆对象的实现细节从它们的一般用例中分离。

简单来说,就是工厂模式生产过程中的规格具有一些相似性,我们在制造前先把规格定义好,后续工厂实际加工过程中,只需要按照规格进行实施即可。

我们来看下代码:

function AbstractVehicleFactory() {
    const _interface = {}
    return {
        getIns(key, context) {
            const fn = _interface[key]
            return fn(context)
        },
        register(key, fn) {
            _interface[key] = fn;
            return AbstractVehicleFactory
        }
    }
}
复制代码

单例模式(Singleton Pattern)

这应该是我们最熟悉的模式之一了,单例模式也称为单体模式,规定一个类只有一个实例,并且提供可全局访问点。比如操作系统的回收站,自始至终只有一个,如果出现两个,就会出现错乱。 我们来看下代码实现:

let Singleton = function(name){
    this.name = name;
    this.instance = null; 
}

Singleton.prototype.getName = function(){
    console.log(this.name);
}

Singleton.getInstance = function(name){
    if(this.instance){
        return this.instance; 
    }
    return this.instance = new Singleton(name);
}

let winner = Singleton.getInstance("winner");   //winner
console.log(winner.getName());
let sunner = Singleton.getInstance("sunner");   //winner
console.log(sunner.getName())
复制代码

上面代码中我们是通过一个变量 instance 的值来进行判断是否已存在实例,如果存在就直接返回 this.instance,如果不存在,就新建实例并赋值给 instance。

我们不管调用多少次,实例对象只有一个。

建造者模式(Builder Pattern)

建造者模式使你能够分步骤创建复杂对象,该模式允许你使用相同的创建代码生成不同类型和形式的对象。

使用Builder的最常见的作用是简化创建复杂对象的客户端代码。客户端可以指导建造者创建,而不需要知道实际工作是如何完成的。

我们来看下代码实现:

function Builder() {
    this.ins = null;
    this.step1 = function() {
        this.ins = new Ins();
    };


    this.step2 = function() {
        this.ins.init();
    };


    this.get = function() {
        return this.ins;
    };
}
复制代码

建造者模式主要用于“分布构建一个复杂的对象”,它很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,并且建造者模式解耦了对象本身与构建过程,使得我们不用关心具体的建造过程。

原型模式(Prototype Pattern)

如Java这类语言,是通过类继承的,而Javascript的继承模式是原型,所以,我们实现远行继承可以基于原生能力。这一模式不仅仅是实现继承的一种简单方式,它顺便还能够带来一点性能上的提升:当定义对象的一个方法时,它们都是使用引用创建的(因此所有的子对象都指向同一个函数),而不是创建属于它们的单独的拷贝。

我们来看下代码实现:

var myCar = {
  name: "myCar",
  drive: function () {
    // TODO
  },
  panic: function () {
    // TODO
  }
};

var yourCar = Object.create(myCar);
console.log(yourCar.name);