美文网首页
单例模式

单例模式

作者: 李友胜 | 来源:发表于2019-08-22 21:13 被阅读0次

单例模式的定义:保证一个类仅有一个实例,并提供一个访问他的全局访问点。

透明的单例模式

我们现在的目标是实现一个透明的单例类,用户丛这个类中创建对象的时候,可以像使用其他任何普通类一样。在下面的例子中,我们将使用CreateDiv单例类,他的作用是负责在页面中创建唯一个的div节点,代码如下:

var CreateDiv = (function () {
    var instance;
    var CreateDiv = function (html) {
        if (instance){
            return instance
        }
        this.html = html;
        this.init()
    }

    CreateDiv.prototype.init = function () {
        var div = document.createElement('div')
        div.innerHTML = this.html;
        document.body.appendChild(div)
    }
    return CreateDiv
})()

var a = new CreateDiv('div1')
var b = new CreateDiv('div2')

console.log( a=== b) // true

虽然现在完成了一个透明的单例类的编写,但他同样有一些缺点。在这段代码中,CreateDiv构造函数扶着了两件事情,1.创建对象和执行初始化方法init,2.保证只有一个对象。
假设我们某天需要利用这个类,在页面冲创建很多个div,即要让这个类从单例类变成一个普通可以产生多个实例的类,那就需要改写CreateDiv构造函数

用代理实现单例模式

现在我们引入代理类的方式,解决上面的问题,首先把扶着管理单例的代码移除,使它变成一个普通的创建div的类

var CreateDiv = function (html) {
    this.html = html;
    this.init()
}

CreateDiv.prototype.init = function () {
    var div = document.createElement('div')
    div.innerHTML = this.html;
    document.body.appendChild(div)
}

var ProxySingletonCreateDiv = (function () {
    var instance;
    return function (html) {
        if (!instance) {
            instance = new CreateDiv(html)
        }
        return instance;
    }
})()

var a = new ProxySingletonCreateDiv('a')
var b = new ProxySingletonCreateDiv('b')
console.log( a === b) 
javascript中的单例模式
// 1.使用命名空间
var namespace = {
    a: function () {
        console.log(a)
    },
    b: function () {
        console.log(b)
    }
}

// 2.使用闭包封装私有变量
// 这种方法把一些变量封装在闭包的内部,只暴露一些接口和外界通信
var user = (function () {
    var _name = 'lusen', _age = 26;
    return{
        getName: function () {
            return _name
        },
        getAge: function () {
            return _age
        }
    }
})()
// 我们用下划线来约定私有变量,他们被封装在闭包产生的作用域中,
//外部是访问不到这两个变量的,这就避免了对全局的污染
惰性单例

惰性单例指的是在需要的时候去创建对象实例。

我们现在实现一个点击按钮弹出对话框的demo,代码如下:

var createDialog = function () {
    var div = document.createElement('div')
    div.innerHTML = '我是弹框'
    div.style.display = 'none'
    document.body.appendChild(div)
    return div
}

document.getElementById('btn').onclick = function () {
    var div1 = createDialog()
    div1.style.display = 'block'
}

虽然现在达到了惰性的目的,但失去了单例的效果。当我们每次点击登录按钮的时候,都会创建一个新的div,这时候我们可以用一个变量来判断是否创建过div了,代码如下:

var createDialog = (function () {
    var div;
    return function (){
        if (!div) {
            var div = document.createElement('div')
            div.innerHTML = '我是弹框'
            div.style.display = 'none'
            document.body.appendChild(div)
        }
        return div
    }
})()
document.getElementById('btn').onclick = function () {
    var div1 = createDialog()
    div1.style.display = 'block'
}
通用的惰性单例

上面我们完成了一个可用的惰性单例,但是还有以下问题

  • 微单单一职责原则,创建对象和管理单例的逻辑都放在了createDialog内部
  • 如下下次我们需要创建页面中的一个iframe,就需要重复写一遍代码,这时候需要把管理单例的逻辑在代码里面抽离出来,这些逻辑封装在getSIngle内部,创建对象的fn方法被当做参数传入到getSingle函数中:
var getSingle = function (fn) {
    var result;
    return function () {
        return result || (result = fn.apply(this, arguments))
    }
}

var createDialog = function () {
    var div = document.createElement('div')
    div.innerHTML = '我是弹框'
    div.style.display = 'none'
    document.body.appendChild(div)
    return div;
}

var createSingleDialog = getSingle(createDialog)

document.getElementById('btn').onclick = function () {
    var divDialog = createSingleDialog()
    divDialog.style.display = 'block'
}

在这个例子中,我们把创建实例对象的职责和管理单例的职责分别放置在两个方法里,这两个方法可以独立变化,互不影响,当他们联系在一起的时候,就完成了创建唯一实例对象的功能。

相关文章

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • 单例模式

    单例模式1 单例模式2

  • java的单例模式

    饿汉单例模式 懒汉单例模式

网友评论

      本文标题:单例模式

      本文链接:https://www.haomeiwen.com/subject/booosctx.html