fi3ework / blog

📝
861 stars 51 forks source link

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

Open fi3ework opened 6 years ago

fi3ework commented 6 years ago
fi3ework commented 6 years ago

单例模式

普通单例模式

分析:

  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,所以没有关系,真正的单例都是各个子类的静态属性

```js
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