fi3ework/blog

设计模式之「创建型模式」

fi3ework opened this issue · 1 comments

  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)
  • 创建者模式(Builder)
  • 原型模式(Prototype)
  • 单例模式(Singleton)

单例模式

普通单例模式

分析:

  1. 使用代理类来遵守 单一职责原则
  2. 实现了惰性单例
class User {
  constructor(name, age) {
    this.name = name || 'no-one'
    this.age = age || 0
    this.init()
  }

  init() {
    console.log(`hello, I'm ${this.name}, I'm ${this.age} years old`)
  }

}

// 普通单例模式
let ProxySingletonUser = (function() {
  let instance
  return function(name) {
    if (!instance) {
      instance = new User(name)
    }
    return instance
  }
})()

let a = ProxySingletonUser('Tom')
let b = ProxySingletonUser('Jerry')

ES6 的单例类

单例模式的核心就是:创建一个单例的对象,这个对象与每个类的实例的生命周期无关,而是与类挂钩。
我们用 ES6 来实现这么一个模块

分析:

  1. 可以直接作为模块 export default
  2. 虽然 singleton 被不同继承了 Singleton 的子类共享,但它只作为一个不可被外部引用的 key,所以没有关系,真正的单例都是各个子类的静态属性
const singleton = Symbol('singleton');

export default class Singleton {
  static get instance() {
    if (!this[singleton]) {
      this[singleton] = new this;
    }

    return this[singleton];
  }

  constructor() {
    let Class = new.target; // or this.constructor

    if (!Class[singleton]) {
      Class[singleton] = this;
    }

    return Class[singleton];
  }
}

调用

class User extends Singleton {
  constructor(name, age) {
    super()
    this.name = name
    this.age = age || 0
    this.init()
  }

  init() {
    console.log(`hello, I'm ${this.name}, I'm ${this.age} years old`)
  }
}

console.log(
  User.instance === User.instance,
  User.instance === new User(),
  new User() === new User()
) // true, true, true