JavaScript设计模式之单例模式

发布于 / 学习

介绍

  • 系统中被唯一使用
  • 一个类只有一个实例

实例

  • 购物车
  • 登录框

UML类图

image

  • 外部无法直接newSingleObject
  • 通过getInstance()方法返回SingleObject对象

代码演示

单例模式需要用到java的private特性
– 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(){
            System.out.print('login...')
        }
    }
  • js模拟实现单例模式
     //js模拟实现单例模式
    class SingleObject{
        login(){
            console.log('login....')
        }
    }
    //定义一个SingleObject对象的getInstance静态方法
    //注意getInstance是一个自执行函数 funa()()
    SingleObject.getInstance = (function () {
        let instance  //定义一个唯一对象
        //闭包
        return function () {
            //如果instance 不存在 就只new一次
            if(!instance){
                instance = new SingleObject()
            }
            return instance
        }
        //返回一个instance
    })()


    let obj1 = SingleObject.getInstance()
    obj1.login()


    let obj2 = SingleObject.getInstance()
    obj2.login()

    console.log('obj1===obj2',obj1===obj2)

    let obj3 = new SingleObject()
    obj3.login()
    console.log('obj1===obj3',obj1===obj3)
  • 结果
    image
  • 发现login打印了两次,而且obj1===obj2说明两个对象完全相等
  • 如果是直接new出来的SingelObject发现与单例模式实现的并不是同一个对象

使用场景

  • jq只有一个$
  • 登陆框
  • 其他

jq只有一个$

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

登录框场景

    class LoginForm{
        constructor(){
            this.state = 'hide'
        }
        show(){
            if(this.state === 'show'){
                console.log('已经显示')
                return
            }
            this.state = 'show';
            console.log('登陆框显示 success')
        }
        hide(){
            if(this.state === 'hide'){
                console.log('已经隐藏')
                return
            }
            this.state = 'hide';
            console.log('登陆框隐藏 success')
        }
    }
    LoginForm.getInstance = (function () {
        let instance
        return function () {
            if(!instance){
                instance = new LoginForm()
            }
            return instance
        }
    })()

    //测试
    let login1 = LoginForm.getInstance()
    login1.show()

    let login2 = LoginForm.getInstance()
    login2.hide()

    console.log('login1 === login2',login2===login1)

其他

  • 购物车跟登陆一样
  • vuex和redux中的store(全局只有一个store)

代码

https://github.com/ahwgs/design-pattern-learning/tree/master/4.JavaScript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F

本文采用 CC BY-NC-SA 3.0 Unported 协议进行许可
本文链接: https://www.ahwgs.cn/javascriptshejimoshizhidanlimoshi.html