javaScript设计模式学习笔记

146 阅读3分钟

本文只提供基础demo,深入了解请自行google~

1.构造器模式

如何避免反复出现

var info = {}
info.name = '大头灰',
info.sex = '男',
info.age = 28

var info2 = {}
info2.name = '小头灰',
info2.sex = '男',
info2.age = 28
...

等这些形式出现,这种时候函数的作用就出现了

function Info(name, sex, age){
    this.name = name
    this.sex = sex
    this.age = age
  }
  var info1 = new Info('大头灰', '男', 28)

这就是最基本的构造函数的作用

接下来再看看用calss怎么实现吧,和构造函数没啥区别。

 class Info {
    constructor(name, sex, age) {
      this.name = name
      this.sex = sex
      this.age = age
    }
  }
  var info = new Info('大头灰', '男', 28)

好了第二个

2.原型模式

用于生成重复的一类对象

原型是通过prototype的方式,不知道原型继承这些的,可以去搜一搜,我忘了我前面有没有写过了,this写了。

继续举个栗子

function Count(x, y, z) {
    this.x = x
    this.y = y
    this.z = z
    this.sums = sumCount
  }
  function sumCount() {
    return this.x + this.y + this.z
  }
  var count = new Count(12, 22, 28)
  count.sums()

很多时候大部分朋友都喜欢这个样子写。但是完全可以通过原型的方式,为什么?因为要的就是求出值的相加,这里有作用域的知识点,不知道的也去补补课

 function Count(x, y, z) {
    this.x = x
    this.y = y
    this.z = z

  }
  Count.prototype.sumCount = function () {
    return this.x + this.y + this.z
  }
  var count = new Count(12, 22, 28)
  count.sumCount()

把方法放在原型链上,也是可以的。再复习一下原型链的概念吧。一个对象,查找属性时,先从自身查找,如果找不到,再顺着prototype向上找,一直到最顶层,直到null为止

3.构建者模式

用于生成确切的对象

   function Count() {
    this.x + this.y
  }
  function Builder() {
    this.count = new Count()
    this.setX = function (x) {
      // 在这些地方就可以写一些。判断方法
      this.count.x = x > 10 ? 1000 : x
    }
    this.setY = function (y) {
      // 这里也可以,算是提供一种验证方式吧
      this.count.y = y
    }
    this.bulid = function () {
      return this.count
    }
  }

  var num = new Builder()
  num.setX(11)
  num.setY(15)
  var number = num.bulid()
  console.log(number)

4.工厂模式

可以很快的生成一类对象,而且每次返回的对象都是新的对象,就是你把需求给工厂,然后工厂一批一批的返回货给你。

 function TypeJudge(name, typeArr) {
    this.name = name
    this.typeArr = typeArr
  }
  function typeJudge(name, type) {
    switch (type) {
      case 'string': return new TypeJudge(name, ['1', '2', '3'])
        break;
      case 'number': return new TypeJudge(name, [1, 2, 3])
        break;
      case 'boole': return new TypeJudge(name, [true, false])
        break;
      default: return '就判断这么多了'
    }



  }
  var type1 = typeJudge('这是字符串', 'string')
  var type2 = typeJudge('这是数字', 'number')

5.单列模式

无论怎么构造,都只返回一个实例

 function Res() {
    if (Res._this) {
      return Res._this
    } else {
      this.num = 10
      Res._this = this
    }
  }
  var a = new Res()
  var b = new Res()
  a.num = 1000
  console.log(a)
  console.log(b)

6.观察者模式

引用一下别人的话

  • 被观察对象
    • 可以输入信息、更新信息
    • 接受观察者的注册
    • 更新消息推送给已注册的观察者集合
  • 观察对象
    • 接收被观察者推送的更新消息

优点

  • 解耦了表示层和数据逻辑层
  • 简化一对多系统的设计
  • 符合开闭原则,增加观察者无需更改被观察者代码

缺点

  • 观察者增多会增加通知成本
  • 观察者如果与被观察者相互依赖,则可能触发死循环
  • 观察者不知道被观察者数据是如何变化的
  // 接收被观察者推送的更新消息
  class User {
    notify(msg) {
      console.log('新消息' + msg)
    }
  }
  // 注册的观察者集合
  class Classify {
    temp: any;
    constructor() {
      // 用个数组保存观察者
      this.temp = []
    }
    subs(user) {
      // 添加观察者
      this.temp.push(user)
    }
    send(msg) {
      // 消息传递给User
      this.temp.forEach(element => {
        element.notify(msg)
      });
    }
  }

  let a = new Classify()
  let a2 = new User()
  let a3 = new User()

  let b = new Classify()
  let b2 = new User()
  let b3 = new User()

  let ab = new User()

  // a只观察a的
  a.subs(a2)
  a.subs(a3)  
  a.subs(ab)  // 我ab都要看
  a.send('我来添加a1的消息')
  
// b只观察b的
  b.subs(b2)
  b.subs(b3)
  b.subs(ab)  // 我ab都要看
  b.send('我来添加b1的消息')