JavaScript设计模式:单体模式
单体模式:
@单体模式用于创建命名空间,将系列关联的属性和方法组织成一个逻辑单元,减少全局变量。
逻辑单元中的代码通过单一的变量进行访问。
@一个单体对象由对象本身 和 访问这个对象的变量组成。
此变量通常为全局变量,所以单体对象能在页面任何位置被访问,故此变量可看做单体对象内部属性和方法的一个命名空间。
@三个特点:
① 该类只有一个实例;
② 该类自行创建该实例,即在该类内部创建自身的实例对象;
③ 向整个系统公开这个实例接口。
@单体弊端:
耦合度高,不好单元测试。
@适合场合:
提供命名空间,增加代码模块性,惰性加载,分支功能。
1、基本结构:
var Singleton = { attr1 : 1, attr2 : 'hello', method1 : function(){alert(this.attr2);}, method2 : function(arg){} }
1.1上例的方式,对象Singleton的所有成员是公开的,在执行到变量Singleton时,会加载(实例化)自身,即非惰性加载。
1.2method1中用this访问单体的其他成员会存在一些风险,因为method1的上下文不是总指向Singleton对象。
如,当方法绑定到事件监听器时,this指向dom元素而失效,这时会提示undefined,故最好使用单体对象的全名访问属性和方法。
2、闭包 实现私有成员的单体,亦称为模块模式(module pattem)
2.1闭包函数 返回的是一个字面量作为单体对象。在继承中返回的是一个构造函数,思路是一样的,利用闭包。
2.2单体模式非常适合使用闭包实现私有方法,因为单体只会实例化一次,没有每次实例化都需要一份私有成员占用内存的顾虑。
var Singleton = (function(){ var attr = 1,
fn = function(){}; return { //return的都是公有成员,其他私有 method : function(){ fn(); }, getAttr : function(){ return attr; } }; })();
2.3因为单体会被实例化一次,故构造函数中声明的所有成员值会被创建一次。
上例,关键字var定义了私有成员,返回了一个公开的接口method和getAttr。
今后,修改实现时只需修改私有成员,method和getAttr接口不变。
3、闭包实现私有成员的惰性实例化单体,惰性实例化(lazy Instantiation)/惰性加载
3.1前面提到的单体模式的实现 都是在脚本加载时即创建的。当一个单体对象需要加载大量数据时,在需要时再创建单体对象会更好。
3.2单体放在constructor()函数中,getInstance函数用于控制单体加载。
使用形式:MyNamespace.Singleton.getInstance().publicMethod1();
对于长的命名空间可以用别名,var MNS = MyNamespace.Singleton; 可使用别名代替this!
上述,用于需要大量数据的单体 直到需要时才实例化。对于命名空间、特定网页专用代码 和 实用的工具方法不使用。
缺点:代码复杂,不直观。
3、分支技术Branching:将浏览器之间的差异封装到动态方法,适用于解决浏览器之间的差异。
通过return (someCondition) ? objectA : objectB;3
缺点:分支中,objectA 和 objectB都被创建了,并保存在内存中了,但只用到一个。
需要在 计算时间 和 占用内存 两者中取舍。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述