设计模式——单例模式

143 阅读1分钟
  1. 定义

保证一个类仅有一个实例,并提供一个访问它的全局访问点 实现方式就是使用闭包,保存这个实例对象,在这个实例对象不为空的情况下,不新建实例对象,而是返回该实例

  1. 核心

确保只有一个实例,并提供全局访问

  1. 实现

假设要设置一个Person类,多次调用也仅设置一次,我们可以使用闭包缓存一个内部变量来实现这个单例

        function Person(name) {
            this.name = name
        }
        Person.prototype.getName = function () {
            console.log(this.name);
        }
        let SinglePerson = (
            function () {
                var person = null
                return function (name) {
                    if (!person) {
                        person = new Person(name)
                    }
                    return person
                }
            }
        )()
        SinglePerson("hzm").getName()//hzm
        SinglePerson("dmt").getName()//hzm
        SinglePerson("zmh").getName()//hzm
       

这是比较简单的做法,但是假如我们还要设置一个HR呢?就得复制一遍代码了

所以,可以改写单例内部,实现地更通用一些

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

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

        function getSingle(fn) {
            var instance = null;
            
            return function () {
                if (!instance) {
                    instance = fn.apply(this, arguments)
                }
                return instance
            }
        }
        let getSinglePerson = getSingle(function (name) {
            return new Person(name)
        })
        let getSingleHR = getSingle(function (name) {
            return new HR(name)
        })
        getSinglePerson("dmt").getName()
        getSinglePerson("zmh").getName()
        getSingleHR("huahua").getName()
        getSingleHR("lili").getName()

上面的代码每一次执行getSingle函数都会形成一个闭包,相当于一个存储一个实例对象就要建立一个闭包。优化如下:

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

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

        let getSingle= (function () {
            var instances={}
            return function (fn,args) {
                if (!instances[fn]) {
                    instances[fn] = fn.apply(this, args)
                }
                return instances[fn]
            }
        })();
        
        let singlePerson = function (name) {
            return new Person(name)
        }
        let singleHR = function (name) {
            return new HR(name)
        }
        getSingle(singlePerson,["hzm"]).getName()
        getSingle(singlePerson,["dmt"]).getName()
        getSingle(singleHR,["hr1"]).getName()
        getSingle(singleHR,["hr2"]).getName()

将所有的实例对象都存储到一个一个对象中,使用一个闭包去存储这个对象

来源