• Javascript 设计模式之一单例模式


    1、什么是单例模式

    单例模式参考链接:https://www.cnblogs.com/xuwendong/p/9633985.html

    单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。

    许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

    单例的实现主要是通过以下两个步骤

    1. 将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;
    2. 在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用  

      

    2、单例模式的应用场景

     适用场景:

    • 1.需要生成唯一序列的环境
    • 2.需要频繁实例化然后销毁的对象。
    • 3.创建对象时耗时过多或者耗资源过多,但又经常用到的对象。 
    • 4.方便资源相互通信的环境  

      

    3、在Javascript中的实现方式

    目标为实现一个类,让这个类只有一个实例对象,即多次new这个类,也只返回第一次实例化时生成的对象,

    假设我们有一个超级管理员类

     1 // 设计一个超级管理员类
     2 class Super {
     3   constructor(name, age) {
     4     this.title = '超管';
     5     this.name = name;
     6     this.age = age;
     7   }
     8 
     9   // 获取名字
    10   getName = () => {
    11     return this.name
    12   }
    13 }

    一般系统中超级管理员有且仅有一个,那么生成这个类的实例对象,只能生成一次,我们需要一个方法来控制

     1 // 设置一个生成单例的方法
     2 const getSingleFun = (fn) => {
     3   let instance = null
     4   return (...args) => {
     5     if (!instance) {
     6       instance = fn.call(null, ...args)
     7     }
     8     return instance;
     9   }
    10 }

    这样我们操作一下来看

    1 // 单例模式的方法
    2 const singleSuper = getSingleFun((...args) => {
    3   return new Super(...args);
    4 })

    然后我们多次调用这个方法,传入不同的参数,看是否生成的实例对象是唯一的

    1 const super0 = singleSuper('奥巴马', 50);
    2 const super1 = singleSuper('特朗普', 74);
    3 const super2 = singleSuper('乔拜登', 78);
    4 
    5 console.log(super0)
    6 console.log(super1);
    7 console.log(super2);
    8 console.log(super1 === super2) // 返回true

    我们会发现虽然多次调用方法,并传入了同样的参数,但返回的实例对象都是第一次调用的值

     那么如何设置一个通用的方法呢?

     1 const getSingle = (className) => {
     2   if (typeof className !== 'function') {
     3     throw('参数必须为一个类或一个函数')
     4   }
     5   const single = (fn) => {
     6     let instance = null
     7     return (...args) => {
     8       if (!instance) {
     9         instance = fn.call(null, ...args)
    10       }
    11       return instance;
    12     }
    13   }
    14   const fn = (...args) => new className(...args);
    15   return single(fn);
    16 }
    17 
    18 const x = getSingle(Super)
    19 
    20 const x1 = x('李大师', 123)
    21 const x2 = x('李大品', 234)
    22 
    23 console.log(x1)
    24 console.log(x2)
    25 console.log(x1 === x2)

    这个通用方法就可以实现了

  • 相关阅读:
    手写一个简易版的Vue-Router,包含VueRouter的基本功能
    Odoo14学习笔记(6) 报psycopg2.errors.UndefinedColumn问题解决办法
    Odoo14学习笔记(5) 通过onchange机制自动计算“工龄”
    Odoo14学习笔记(4) 通过计算字段Compute Field自动计算工龄
    Odoo14学习笔记(3) 使用_sql_constraints对字段做Unique约束
    Odoo14学习笔记(2) 创建一个新应用Application
    Odoo14学习笔记(1) 安装时报关系"ir_modul"不存在问题
    大叔学Spring Boot笔记(15)MyBatis-Plus中LambdaQueryWrapper的使用
    java 读取excel 神器easyPoi
    通过PROFINET实现S7-1200与CU320-2 PN S120通讯
  • 原文地址:https://www.cnblogs.com/liquanjiang/p/15588389.html
Copyright © 2020-2023  润新知