首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >惰性单例分析与学习

惰性单例分析与学习

作者头像
RobinsonZhang
发布2018-08-28 13:10:11
4020
发布2018-08-28 13:10:11
举报

前言

本文基于你已经知道单例模式的要点,本文内容借鉴于《javascript设计模式与开发实践》这本书,做出了整理和一些思考。

建议阅读时间:10-15min

基础回顾

惰性单例是指需要的时候才创建对象实例。这种技术非常好用,而且在实际开发中被大范围的使用。

比如我们借鉴这种思想,实例对象是需要的时候才被创建而不是开始就创建,所以优化后的写法是这样的。

Singleton.getInstance = (function(){
    let instance = null;
    return function(name){
    if(!instance){
     instance = new Singleton(name)
    }
    return instance
    }
    }
)()

案例推进

下面的案例我们将结合页面中最常见的登录窗来进行说明。显然它符合单例的基本要求。

方案 一 :页面加载完成就创建好,然后通过点击事件控制其显示

备注 :为了简化语法,假设是在jq库下。

let  loginLayer = (function(){
    let  $div = $("<div></div>") ;
    $div.html('我是登录弹窗').css("display","none") ;
    $("body").append($div);
    return $div;
})()

$("#login").click(function(){
loginLayer.show();
})

优化1 :点击登录时才创建

上面的方法中,很显然是页面载入必然创建,而我们有些场景下是不需要登录弹窗的。

let  loginLayer = function(){
    let  $div = $("<div></div>") ;
    $div.html('我是登录弹窗').css("display","none") ;
    $("body").append($div);
    return $div;
}

$("#login").click(function(){
let loginLayer = loginLayer();
loginLayer.show();
})

优化2:按照上面的思路,重复创建销毁也不好

那么如何确认页面中是否已经有一个弹窗?这时候就需要一个全局变量来记录是否已经创建过。

let  loginLayer = (function(){
    let $div ;
    return function(){
    if(!$div){
        $div = $("<div></div>") ;
        $div.html('我是登录弹窗').css("display","none") ;
        $("body").append($div);
    }
    return $div;
    }
})()

$("#login").click(function(){
loginLayer.show();
})

抽离通用的单例模式

上面的思考中,我们完成了一个较好的单例模式的实践,但是其不具有良好的通用性,在下次创建一个iframe或者其他控件的时候,我们还是需要把它代码复制粘贴一遍。

所以我们看下是否有更好的思路,能够比较符合单一职责原则,创建对象和管理单例的逻辑都放到一个工具函数中管理?答案是肯定的。

首先分析单例的核心逻辑 :

let obj ;
if(!obj){
    obj = xxx;
}

实现单例函数的核心逻辑 :

let getSingle = function (fn){
 let result ;
 return function(){
    return result || (result = fn.apply(this,arguments)); 
 }
}

拓展

上述的通用函数可以用于各个场景,创建对象,绑定事件都可以。

比如 :只绑定一次的事件,不想因为每次追加事件重复绑定 。

原来的写法 需要借助jq one

let bindEvent = function(){
    $("div").one("click",function(){
    alert("click")
    })
}

let render = function (){
console.log("渲染数据");
bindEvent();
}

现在写法可以是 :

let bindEvent = getSingle(function(){
    $("div").click(function(){
    alert("click")
    })
    return true;
})

let render = function (){
console.log("渲染数据");
bindEvent();
}

总结

单例模式是一种简单但是非常实用的单例模式,特别是惰性单例,在需要的时候才创建,并且只创建一个,创建对象和管理实例放在两个不同方法中,这两个方法组合起来更能发挥单一职责和单例模式的作用。

友情链接

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 基础回顾
  • 案例推进
    • 方案 一 :页面加载完成就创建好,然后通过点击事件控制其显示
      • 优化1 :点击登录时才创建
        • 优化2:按照上面的思路,重复创建销毁也不好
        • 抽离通用的单例模式
        • 拓展
        • 总结
        • 友情链接
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档