JS设计模式之单例模式

概述

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。该模式下,在该实例子不存在的情况下,可以通过一个方法创建一个类来实现创建类的新实例;如果实例已经存在,它会返回该对象的应用。

实现方法

ES5

var Singleton = function() {
    this.instance = null;
}
//核心方法,获取或创建实例的方法
Singleton.getInstance = function() {
    if(!this.instance) {
        this.instance = new Singleton();
    }
    return this.instance;
}
//a2
var a1=Singleton.getInstance();

ES6

class Singleton{
	constructor(){
		this.instance=null;
	}
	//静态方法
	static getInstance(){
		if(!this.instance){
			this.instance=new Singleton();
		}
		return this.instance;
	}
}
//调用
var a2=new Singleton.getInstance();
应用场景

全局唯一性消息框(对话框):场景要求用户点击弹出按钮弹出一个消息框,点击关闭按钮消息框消失。对于没有使用过设计模式的开发者可能有这样的思路:如在页面提前装载消息框,用户点击弹出或关闭弹出按钮时设置元素的显示状态,即display样式。这个方法有这些缺点:消息框需要在页面加载完成后就要初始化好;用户不需要消息框的时候DOM元素还存在;使用单例设计模式可以在用户点击弹出按钮时才创建消息框,并追加到页面中,点击关闭消息框时把该DOM元素移除并销毁实例子。但是也有这些缺点:添加和移除DOM元素比修改DOM元素的display样式更消耗性能。

<!DOCTYPE HTML>
<html>
<title>单例设计模式</title>

<head>
  <meta charset="utf-8">
  <style type="text/css">
    .msg-mask {
      position: absolute;
      background: #000;
      opacity: 0.5;
      height: 40px;
      top: 50px;
      left: 50%;
      transform: translateX(-50%);
      display: flex;
      align-items: center;
    }

    .msg-mask>.msg-body {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 0 50px;
      color: #fff;
    }
  </style>
</head>

<body>
  <h2>本例使用单例的思想实现需要动态的向页面追加DOM元素的功能,并确保追加DOM元素时只追加一次。</h2>
  <h3>传统方法:</h3>
  <button onclick="showNormalMsg()">打开消息框</button>
  <button onclick="closeNormalMsg()">关闭消息框</button>
  <h3>单例方法:</h3>
  <button onclick="showSingletonMsg()">打开消息框</button>
  <button onclick="closeSingletonMsg()">关闭消息框</button>
  <script type="text/javascript">
    function initMsg() {
      const msgTemplate = `
         <div class="msg-mask" id="normalMsg" style="display:none">
           <div class="msg-body">消息内容</div>
         </div>
       `;
      document.body.innerHTML += msgTemplate;
    }
    //初始化对话框
    initMsg();

    function showNormalMsg() {
      document.getElementById('normalMsg').style.display = "flex";
    }

    function closeNormalMsg() {
      document.getElementById('normalMsg').style.display = "none";
    }
  </script>
  <script type="text/javascript">
    class SingletonMsg {
      constructor() {
        this.instance = null;
      }
      static show() {
        if (!this.instance) {
          this.instance = new SingletonMsg();
          const msgTemplate = `
             <div class="msg-mask" id="singletonMsg">
               <div class="msg-body">消息内容</div>
             </div>
           `;
          document.body.innerHTML += msgTemplate;
        }
        return this.instance;
      }
      static close(){
        if(this.instance){
           document.body.removeChild(document.getElementById('singletonMsg'));
        }
        this.instance=null;
      }
    }

    function showSingletonMsg() {
      SingletonMsg.show();
    }

    function closeSingletonMsg() {
      SingletonMsg.close();
    }
  </script>
</body>

</html>

总结

对于使用全局缓存,全局唯一或高频操作的使用场景,使用单例设计模式可以节省内存,减少资源消耗。然而单例模式在前端的使用场景和案例相对较少,常见于后端的数据库单例连接与数据库线程池连接等使用场景,桌面开发中的单窗口实例。前端开发者应该根据需要慎重使用单例设计模式,不要一味追求设计模式而导致开发速度的减缓,影响代码的维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值