JavaScript设计模式(一):单例模式实现与应用
先提出一个问题为什么要学习设计模式难道是提出一个代码形容词是为了让代码看起高大上 or 装逼先看下设计模式的定义在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。我的个人理解就是设计模式是前人对于解决问题提炼出来的一种思想其实我们日常代码中就会用到一些设计模式。像我们平时用的装饰器可以看作是装饰者模式ES6 提供的proxy也可以看作是代理模式像 JavaScript 中的自定义事件 addEventListener就采用的是发布订阅模式。设计模式是为了让你的代码变得简单而优雅。有很高的可重用性、可维护性以及可扩展性。设计模式有很多种我们今天先来盘一下最常用和经典的设计模式之一单例模式。1、单例模式定义单例模式的定义保证一个类仅有一个实例并提供一个访问它的全局访问点。其实就是第一次访问会进行初始化创建一个实例后面访问的时候拿到的都是这个实例不会再重新创建。classSingleton{constructor(name){this.namename;}getName(){returnthis.name;}staticgetInstance(name){returnthis.instance||(this.instancenewSingleton(name))}}constinstance1Singleton.getInstance(zs)constinstance2Singleton.getInstance(lisi)console.log(instance1instance2)// true在单例类Singleton上定义一个获取实例的getInstance方法第一次调用getInstance的时候创建一个Singleton实例保存在instance属性上后面再获取就直接取this.instance。但是这样会出现一个问题用户如果不调用getInstance而直接去new Singleton这样还是会创建多个实例出来这样不是我们所期望的。2、优化版我们定义一个Singleton类并用一个instance变量来保证在new 多次时全局Singleton类实例的唯一性。letinstancenull;classSingleton{constructor(name){this.namename;if(!instance){instancethis;}returninstance;}}constinstance1newSingleton(zs)constinstance2newSingleton(lisi)console.log(instance1instance2)// true3、更优雅的实现使用代理模式实现单例其实我们可以用ES6的proxy来实现单例其代码如下classPerson{constructor(name,age){this.namename;this.ageage;}}functionsingleton(className){letinstancenull;returnnewProxy(className,{construct(target,args){if(!instance){instanceReflect.construct(target,args);}returninstance;}})}constProxyPersonsingleton(Person);constperson1newProxyPerson();constperson2newProxyPerson();console.log(person1person2);// true4、代理模式实现单例的好处解耦和单一职责原则我们使用了代理之后等于在我们使用的客户端和实际对象两者中间加入了一层代理对象而代理对象相当于一个黑盒子而对我我们客户端来说使用的时候不关心他里面的逻辑和实现细节只关心它给我们提供了哪些功能和接口调用就完事了 这样遵循了单一职责原则提高了代码的可维护性。控制访问和延迟加载其实也可以说就是安全性在代理层做校验可以说是再好不过了可以先把一些错误情况给拦截掉起到访问控制的效果然后也可以根据情况决定时候延迟创建实例也就是我们说的惰性单例这样对于CPU密集型的实例来说同时也能大大提高性能。扩展性我们可以在代理层通过继承或实现相同的接口来扩展实际对象的功能这样就可以做到不修改实际对象的源码又增加上了扩展功能。5、单例模式的应用假如我们要创建一个全局唯一的弹框我们很容易先写在创建弹框的代码:constdivdocument.createElement(div)div.innerHTML我是全局唯一的弹框div.style.displaynonedocument.body.appendChild(div)创建弹框我们有两种思路我们可以在一开始渲染页面的时候就创建这个弹框然后通过控制display进行显示隐藏当然也可以惰性的懒加载第一次用到的时候再去创建弹框为了性能考虑我们当然是选择后者。htmlbodybuttonidbtn显示弹框/button/bodyscriptconstgetSingle(fn){letinstancenullreturn(...args){returninstance||(instancefn.apply(this,args))}}constcreateModel(){constdivdocument.createElement(div)div.innerHTML我是全局唯一的弹框div.style.displaynonedocument.body.appendChild(div)returndiv;}constcreateSingleModelgetSingle(createModel);btn.addEventListener(click,(){constmodelcreateSingleModel();model.style.displayblock;})/script/html我们先把创建弹框的逻辑抽离到createModel方法中然后我们创建一个管理单例的方法getSingle先调用getSingle将createModel交给getSingle去管理这样就实现了唯一性然后在按钮点击的时候在调用getSingle返回的方法就行啦。小结上面介绍Javascript最经典的设计模式之一单例模式简单来说单例就是单实例就是全局只能被创建一次我们还用了代理对象来实现单例用以增加其维护性和扩展性。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2433438.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!