設計モード——単一例モード(JavaScript実現)

4917 ワード

シングルモデルはデザインモードの中で一番簡単なモデルかもしれません.簡単ですが、日常生活とプログラミングの中でよく触れます.今回は一緒に勉強しましょう.
単一の例モード(Singleton Pattern)はまた単量体モードと呼ばれ、一つのクラスが一例しかないことを保証し、その全体的なアクセスポイントを提供する.つまり、同じクラスを使って新しいオブジェクトを作成する場合は、最初に作成したオブジェクトと同じオブジェクトを得るべきです.
実現する
class Singleton {
  constructor() {
    if (Singleton.instance) {
      return Singleton.instance
    }
    Singleton.instance = this
  }
  
  static getInstance() {
    if (Singleton.instance) {
      return Singleton.instance
    }
    return Singleton.instance = new Singleton()
  }
}
Singleton.instance = null

const instance1 = new Singleton()
const instance2 = new Singleton()

console.log(instance1 === instance2)
二(IIIIFE方式)を実現します.
const Singleton = (function() {
    let _instance = null        //     
    
    const Singleton = function() {
        if (_instance) return _instance     //         
        _instance = this
        this.init()                         //      
        return _instance
    }
    
    Singleton.prototype.init = function() {
        this.foo = 'Singleton Pattern'
    }
    
    Singleton.getInstance = function() {
        if (_instance) return _instance
        _instance = new Singleton()
        return _instance
    }
    
    return Singleton
})()

const visitor1 = new Singleton()
const visitor2 = new Singleton()         //     new     
const visitor3 = Singleton.getInstance() //     getInstance     

console.log(visitor1 === visitor2)  // true
console.log(visitor1 === visitor3)  // true
三(ブロックレベルのスコープ方式)を実現する.
let getInstance

{
    let _instance = null        //     
    
    const Singleton = function() {
        if (_instance) return _instance     //         
        _instance = this
        this.init()                         //      
        return _instance
    }
    
    Singleton.prototype.init = function() {
        this.foo = 'Singleton Pattern'
    }
    
    getInstance = function() {
        if (_instance) return _instance
        _instance = new Singleton()
        return _instance
    }
}

const visitor1 = getInstance()
const visitor2 = getInstance()

console.log(visitor1 === visitor2)

//   : true
3つの例のパターン形成を実現する.
/*     */
class FuncClass {
    constructor(bar) { 
        this.bar = bar
        this.init()
    }
    
    init() {
        this.foo = 'Singleton Pattern'
    }
}

/*          */
const Singleton = (function() {
    let _instance = null        //     
    
    const ProxySingleton = function(bar) {
        if (_instance) return _instance     //         
        _instance = new FuncClass(bar)
        return _instance
    }
    
    ProxySingleton.getInstance = function(bar) {
        if (_instance) return _instance
        _instance = new Singleton(bar)
        return _instance
    }
    
    return ProxySingleton
})()

const visitor1 = new Singleton('  1')
const visitor2 = new Singleton('  2')
const visitor3 = Singleton.getInstance()

console.log(visitor1 === visitor2)  // true
console.log(visitor1 === visitor3)  // true
四Proxyを実現
/* Person   */
class Person {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
}

/*           */
function Singleton(FuncClass) {
    let _instance
    return new Proxy(FuncClass, {
        construct(target, args) {
            return _instance || (_instance = Reflect.construct(FuncClass, args)) //    new FuncClass(...args)    
        }
    })
}

const PersonInstance = Singleton(Person)

const person1 = new PersonInstance('   ', 25)
const person2 = new PersonInstance('   ', 23)

console.log(person1 === person2)    // true
五餓漢式と怠け者式を実現します.
class FuncClass {
  constructor() { this.bar = 'bar' }
}

//    
const HungrySingleton = (function() {
  const _instance = new FuncClass()
  
  return function() {
      return _instance
  }
})()

//    
const LazySingleton = (function() {
  let _instance = null
  
  return function() {
      return _instance || (_instance = new FuncClass())
  }
})()

const visitor1 = new HungrySingleton()
const visitor2 = new HungrySingleton()
const visitor3 = new LazySingleton()
const visitor4 = new LazySingleton()

console.log(visitor1 === visitor2)  // true
console.log(visitor3 === visitor4)  // true
単例パターンのまとめ
一例モードで主に解決される問題は資源を節約し、アクセスの一貫性を維持することです.
長所
  • 単一の例のモードは、作成後にメモリに一例しか存在しません.メモリ支出とインスタンス化時のパフォーマンス支出を節約します.特に、作成オーバーヘッドが大きいタイプを重複して使用する必要があります.インスタンスよりも継続的に廃棄し、再実装することができます.単一の例では、データベース接続などのより多くのリソースを節約できます.
  • 単一の例のモードは、ファイルを書く動作のようなリソースの多重占有を解決することができます.例が一つしかないので、一つのファイルの同時動作を回避することができます.
  • は一例だけを使用してもいいし、ゴミ回収メカニズムGCの圧力を低減してもいいです.ブラウザでシステムのカートンが減少し、操作がスムーズになり、CPU資源の占用が少なくなります.
  • 欠点
  • シングルケースのモードは拡張に対して友好的ではなく、一般的に拡張しにくいです.シングルモデルは一般的に自分で実行し、インターフェースがないからです.
  • と単一職責原則の衝突、一つの種類は内部論理のみに関心を持つべきで、外はどうやって実用化するかに関心がない.