js设计模式之单例模式
js设计模式之单例模式
1、定义
保证一个类仅生成一个实例,并可以全局访问。
2、应用范围
单列模式应用非常广泛,有些场景下某些对象只需要一个,比如浏览器中的window对象,全局缓存对象等。在实际开发过程中应用也比较多,比如点击一个按钮产生一个登陆框,无论点击多少次都应该只在第一次产生这个登录框,而在后面点击N次也只能是复用这个登陆框,而非重新创建,这样的场景就可以使用单列模式来创建这个登陆框。
3、实现一个简单的单例模式
//简单版单列模式
const Singleton = function (name) {
this.name = name //这个instance来保存生成的实例 this.instance = null
}
Singleton.prototype.getName = function () {
return this.name
}
//静态方法
Singleton.getInstance = function (name) {
if (!this.instance){ this.instance = new Singleton(name) } return this.instance
}
const A = Singleton.getInstance('A')
const B = Singleton.getInstance('B')
console.log(A === B); //true
console.log(A.getName()); //A
console.log(B.getName()); //A
要实现起来并不复杂,无非就是使用一个私有变量去保存已生成的实例,在下新建时判断是否存在这个实例,若存在直接返回,而不创建就OK了。
4、透明版
透明板也就要用new Constructor的形式创建对象,使用单例的类就像使用普通的类一样。
下面我们使用闭包的形式来写一个单列类,并使用闭包的局部变量来保存已生成的实例。
//透明板单列模式
const Singleton = (function () {
let instance = null //实现一个简单的类 function createDiv(html){ if (instance){ return instance } this.html = html return instance = this } createDiv.prototype.init = function () { let div = document.createElement('div') div.innerHTML = this.html document.body.append(div) } return createDiv
})()
const A = new Singleton('A')
const B = new Singleton('B')
console.log(A === B); //true
5、代理版
代理版本要实现的目标是将定义类的代码和管理单例的代码分开,实现更小粒度的划分,遵循单一职责原则
const Singleton = function (name){
this.name = name
}
const proxySingleton = (function () {
let instance = null return function (name) { if (!instance){ instance = new Singleton(name) } return instance }
})()
6、惰性单例
前面写的例子都是基于'类'的单例模式,其目的在与创建一个唯一的由'类'生成的对象(这里的'类'指的是伪类,也就是我们把javascript中的构造函数当做其他传统语言中的类来进行理解,而其实javascript中是不存在类的的概念,所有对象都是构造函数基于原型克隆出来的,快扯到面向对象去了,这里就不多说了)
理解惰性单例有如下两点
1、而现在要理解的 "惰性单例"的概念,我们的思想不再局限于去实现一个全局唯一的由伪类生成的对象,我们维持的唯一单例可能是一个div,可能是一个列表,也自然可能是一个对象。
2、另外要理解的是 '惰性'二字,也即 我们维持的单例在不需要的情况下是不会产生的,只有在需要的情况才会生成,其实这一点在第二节简单的单例模式里面就已经实现了,只有调用Singleton.getInstance才会生成,并且生成后会一直存在,等待复用
一个例子:
比如我们需要一个登陆框,而在页面上点击登陆就会弹出这个登陆框,无论多次点击生成的都应该是同一个DOM节点,而这个DOM节点只在第一次调用生成,后面点击登陆只会复用这个DOM节点。这里我们维持的唯一单例应该是登陆框的DOM节点,并且是惰性生成的,即永不点击登录,就永远不会生成该DOM节点。
下面给出惰性单例的通用代码
//惰性单例通用代码
const getSingle = function (fn){
let instance = null; return function (){ return instance || (instance = fn.call(this, arguments)) }
}
要实现上面维持登录框单例的例子, 这里说一下思路, fn的功能是产生登录框,并返回登录框的DOM,代码如下
const createLoginLayer = function(){
let div = document.createElement( 'div' ); div.innerHTML = '我是登录浮窗'; div.style.display = 'none'; document.body.appendChild( div ); return div;
};
let createSingleLoginLayer = getSingle( createLoginLayer );
document.getElementById( 'loginBtn' ).onclick = function(){
let loginLayer = createSingleLoginLayer(); loginLayer.style.display = 'block';
};
7、小结
单例模式在开发过程中应用很广泛,特别是惰性单例,所以也是我们必须要掌握的点。然后要再啰嗦几句的就是关于,单一职责原则,开放封闭原则,最少知识原则等等面向对象的概念,无论是上面提到的还是没提到的,我们都需要有一定的了解,熟悉这些原则并应用于实际对于代码质量的提升肯定是巨大的。
原文地址https://www.cnblogs.com/chenlei987/p/11356439.html
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
webgl(three.js)实现室内定位,楼宇bim、实时定位三维可视化解决方案
(写在前面,谈谈物联网展会)上次深圳会展中心举行物联网展会,到了展会一看,80%以上的物联网应用都是在搞RFID,室内定位,我一度怀疑物联网落地方案的方向局限性与市场导向,后来多方面了解才明白,展会上看到的不能体现目前物联网最前沿最广泛的应用,很多大的企业与技术前沿企业没有参与这样的展会,一是不屑于参加,二是展会带来的市场价值实在太少太少,展会最大的价值就是让同行之间再抄一抄(国内大部分企业基本这样,互相山寨),看看各家都做了啥,所以,展会上我们所看到的往往不是企业最核心最好的东西,不能体现当前国内物联网最前沿的技术与发展状况。 前言:GPS、北斗系统将全球地图导航定位发展到了极致的程度,但精确精度还不能达到两米以内, 如何解决解决室内这最后几米的定位问题,国内外各大厂家各出奇招。因为有市场需求所以有资本驱动,室内精确定位在仓库,档案馆,监狱,医院,办公,人员,以及各种高价值重要资产等定位场景中都要这样的需求。室内定位设想应用于人员的管理、机器人仿生、被标签物的定位追踪等等。如果室内定位能够解决精度,延迟,容量三方面瓶颈,其市场应用价值不可限量 技术目标:将非可视内容的可视化呈现,更直...
- 下一篇
Java实现ZooKeeper的zNode监控
Java实现ZooKeeper的zNode监控1 场景设计目的是体验ZooKeeper的Watcher功能。程序监控ZooKeeper的/watcher节点数据变化,当创建或修改数据时,控制台打印当前的数据内容和版本号;当/watcher被删除时,程序退出。 /watcher的创建、修改和删除操作,使用控制台或zkui操作。 2 搭建Maven项目代码相对比较简单,就不用SpringBoot这个大杀器了,使用一个普通的Maven项目即可。 ZooKeeper客户端使用官方提供的Java库,org.apache.zookeeper: zookeeper: 3.5.5。日志框架使用习惯的slf4j+log4j2,ZooKeeper缺省使用的是log4j V1,因此在引入的时候需要excludes。另外,使用了lombok来简化一些代码。 以下是pom.xml的内容 <?xml version="1.0" encoding="UTF-8"?> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.ap...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7安装Docker,走上虚拟化容器引擎之路