谈谈js设计模式- 单例、工厂、观察者(第三篇笔记)

135 阅读2分钟

我正在参加「掘金·启航计划」

前言

我是小白,励志要做技术男神的帅逼,目前住在南京,做了快3年前端工程师,我的第二篇笔记。

做这篇笔记是因为前段时间,我和某人讨论过这个,为了普及一下某人的知识点我写了这篇笔记,这时候我应该@他一下。

基础资料

js设计模式有那些?

  • 单例模式
  • 工厂模式
  • 观察者模式

单例模式

作用:保证一个类(javascript写法function/typescript写法class)只创建了一个实例(javascript中只New了一个实例)。

实现方法: 判断这个类是否存在实例,如果不存在实例则创建一个实例,如果存在实例则直接返回这个实例

  • 用代码表示

    1. javascript

      class User {
          constructor() {
              this.name = 'xm'
          }
          static getInstance() {
              if (!User._instance) {
                  User._instance = new User()
              }
              return User._instance
          }
      }
      const u1 = User.getInstance()
      const u2 = User.getInstance()
      console.log(u1 === u2);
      
    2. typescript

      (function(){
        let instance = null;
        return class{
            constructor(){
              if(!instance){
               //第一次创建实例,那么需要把实例保存
                instance = this;
              }else{
                return instance;
            }
        }
        }
      })()
      let p3= new Person();
      let p4 = new Person();
      console.log(p3===p4)  //true
      

观察者模式

作用:当改变一个对象会同时改变其他对象时,应该使用观察者模式。观察者模式主要作用是解耦。

/*
 * desc:通知者类
 * 1、存储观察者
 * 2、添加观察者
 * 3、移除观察者
 * 4、通知观察者
 */
class Dep {
    constructor() {
        //存储观察者
        this.subs = []
    }

    /**
     * 添加观察者
     * @param {观察者对象} sub 
     */
    addSubs(sub) {
        //确保观察者都有update方法
        if (sub && sub.update) {
            this.subs.push(sub)
        }
    }

    /**
     * 移除观察者
     * @param {需要移除的观察者对象} sub 
     */
    removeSub(sub) {
        this.subs.forEach((item, index) => {
            if (sub.id === item.id) {
                this.subs.splice(index, 1)
                return;
            }
        })
    }

    /**
     * 通知观察者,调用所有观察者内部的update的方法,改变自身状态
     * */
    notify() {
        this.subs.forEach(sub => {
            sub.update()
        })
    }
}

/**
 * 观察者对象
 */
class watcher {
    constructor(name) {
        this.name = name
    }

    //观察者对象都有自己的update方法,来改变自己的工作状态
    update() {
        console.log(`${this.name}收到通知,改变工作状态。`)
    }
}

例子: 背景》 同事张三和李四是公司的摸鱼达人,上班摸鱼已经是手到擒来,顺手拈来,已经到了出神入化的境界,并用金钱收买了公司前台小姐姐(真可耻),老板来了让她告知张三和李四

 <script src="./js/Dep.js"></script>
 <script src="./js/Watcher.js"></script>
 <script>
        //同事张三(需要静观其变,持续摸鱼,需要时刻保持观察前台小姐姐发送的广播通知)
        const tongshi1 = new watcher("张三")

        //同事李四(需要静观其变,持续摸鱼,需要时刻保持观察前台小姐姐发送的广播通知)
        const tongshi2 = new watcher("李四")

        //前台小姐姐要把需要通知的对象收集起来,以便发送广播通知
        const xiaojiejie = new Dep();
        xiaojiejie.addSubs(tongshi1)
        xiaojiejie.addSubs(tongshi2)

        // 等待老板归来...
        // 老板回来了

        // 当老板回来时,前台小姐姐调用自己的notify方法通知同事们
        xiaojiejie.notify()
        // notify 方法被触发, 调用所有观察者内部的方法
    </script>

工厂模式

作用

  • 通过对产品类的抽象使其创建业务主要负责用于创建多类产品实例

代码表示:

// 标准的工厂模式
class Target1 {
    name = ''
    constructor(name: string) {
            this.name = name
    }
    fn() {console.log(this.name)}
}
class Target2 {
    name = ''
    constructor(name: string) {
            this.name = name
    }
    fn() {console.log(this.name)}
}
// 工厂
class Creator {
    create(type, name) {
        if (type === 'A') {
            return new Target1(name)
        }
        if (type === 'B') {
            return new Target2(name)
        }
        throw new Error('Invalid type')
    }
}
const creator = new Creator()
const t1 = creator.create('A', '张三')
const t2 = creator.create('B', '李四')

结语

以上是我的一篇笔记,本人前端小白一只,如果写的不好请各位大佬指正,俺想再学习到更深知识,希望和各位大佬交朋友,希望我的笔记对您提供舒适的观看体验。