600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > js设计模式的讲解与应用 - 【单例模式】

js设计模式的讲解与应用 - 【单例模式】

时间:2022-05-18 05:16:24

相关推荐

js设计模式的讲解与应用 - 【单例模式】

单例模式

一,单列模式的介绍1.概念2.示例场景3.UML 类图如下二,单例模式的应用1.模式特性的说明1-1. java实例1-2. `javaScript`的简单实例 - 存在不透明性1-3. 使用代码实现单例模式 - 完成一个透明的单例1-4. 通用的惰性单例三,单列模式的场景项目中的场景单例模式 vs 单一职责原则

一,单列模式的介绍

1.概念

单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例;

单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2.示例场景

按照面向对象的编程思想,任何东西都可以抽象为一个类,然后可以new出若干个对象。

但是针对某些场景,只能存在唯一的对象;

例如:jQuery中的$; 登录;购物车等;

3.UML 类图如下

二,单例模式的应用

1.模式特性的说明

单例模式需要使用到java的特性(privateES6中并没有使用private的关键字;(暂时还没有规范到ES6中,但typeScript除外)

1-1. java实例

单例模式用到了 java 的一些特性,而es6没有这些特性,所有这里使用java进行演示,代码如下:

public class SingleObject {// 注意,私有化构造函数,外部不能 new ,只能内部能 new !!!!private SingleObject(){}// 唯一被 new 出来的对象private SingleObject instance = null;// 获取对象的唯一接口public SingleObject getInstance() {if (instance == null) {// 只 new 一次instance = new SingleObject();}return instance;}// 对象方法public void login(username, password){System.out.println("login...");}}

使用代码

public class SingletonPatternDemo {public static void main(String[] args) {//不合法的构造函数//编译时错误:构造函数 SingleObject() 是不可见的 !!!//SingleObject object = new SingleObject();//获取唯一可用的对象SingleObject object = SingleObject.getInstance();object.login();}}

单例模式的关键在于不能让外部使用者new出对象,即构造函数是private

这里的关键字样表示:

public公有的

protect受保护

private私有

1-2.javaScript的简单实例 - 存在不透明性

这里通过SingleObject.getInstance来获取SingleObject唯一的类,相对较简单,但存在一个问题;这个类的不透明性SingleObject使用者必须知道这是个单例类;

跟以往的new XXX的方式获取不同,这里使用SingleObject.getInstance来获取对象;实例代码如下:

class SingleObject {login() {console.log('login...')}}SingleObject.getInstance = (function () {let instancereturn function () {if (!instance) {instance = new SingleObject();}return instance}})()// 测试:注意这里只能使用静态函数 getInstance ,不能 new SingleObject() !!!let obj1 = SingleObject.getInstance()obj1.login()let obj2 = SingleObject.getInstance()obj2.login()console.log(obj1 === obj2) // 两者必须完全相等

1-3. 使用代码实现单例模式 - 完成一个透明的单例

这里使用到“单一职责的原则”,将创建对象对象的初始化方法进行分离;

这里把负责管理单例的逻辑移到了代理类ProxySingletonObject中,而实现单例的SingleObject变成一个普通的类,结合起来实现单例的效果;代码实例如下:

// 实例的构造函数class SingleObject {login() {console.log('login...');}}// ProxySingletonObject 引入一个代理类var ProxySingletonObject = (function(){var instance;return function(){if (!instance){instance = new SingleObject();}return instance;}})();var login1 = new ProxySingletonObject()var login2 = new ProxySingletonObject()console.log(login1 === login2, "login1 === login2");

1-4. 通用的惰性单例

单列的逻辑:用一个变量来标志是否创建过对象,如已创建,下次直接返回已创建好的对象;

var obj;if (!obj) {obj = XXX;}

这里将创建实例对象的职责管理单列的职责分开;createLoginLayer的方法可用于创建多种,随时替换方法;

// 创建对象的实例:var createLoginLayer = function(){var div = document.createElement( 'div' );div.innerHTML = '我是登录浮窗';div.style.display = 'none';document.body.appendChild( div );return div;};// 单列的逻辑var getSingle = function(fn) {console.log(fn)var result;return function() {return result || (result = fn.apply(this, arguments))}}// 调用单列的逻辑创建createLoginLayer的单列var createSingleLoginLayer = getSingle( createLoginLayer ); document.getElementById( 'loginBtn' ).onclick = function(){var loginLayer = createSingleLoginLayer(); // 登录框的createLoginLayer只有一个loginLayer.style.display = 'block';};

三,单列模式的场景

常使用中,很多都用到了单例的思想,但是不一定完全按照单例的类图来实现:

项目中的场景

jQuery只有一个 $

在项目中应用jQuery的文件,有且只有一个$,其内部调整逻辑也类似:

// jQuery 只有一个 `$`if (window.jQuery != null) {return window.jQuery} else {// 初始化...}

模拟实现一个登录框购物车redux 和 vuex 的 store

单例模式 vs 单一职责原则

单一职责原则是针对所有的设计,单个功能尽量拆分,一个模块做好一个功能。如果做不好,会带来模块臃肿,不好维护。单例模式是系统的有且只有一份数据,如果不这样做,会出bug;(这里当我们写自己的模块时,进行封装使用引入到项目中,也可多一次创建就可使用;避免多次创建带来不必要的损耗)

设计原则验证:

符合单一职责原则,只实例化唯一的对象没法具体开放封闭原则,但是绝对不违反开放封闭原则

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。