js---简单的设计模式

81 阅读2分钟

1 单例模式

1.1普通的单例模式

var stu1 = {
  name: 'zhangsan',
  age: 18,
  sex: 'boy'
};

var stu2 = {
  name: '李四',
  age: 19,
  sex: 'girl'
};Ï

像上面这样,把描述事物的属性放到一个对象内这种封装方式称为单例模式。单利模式的优点就是解决啦全局变量相互影响相互覆盖的问题,而stu1 和 stu2 又可以称为命名空间

 哈哈没有想到吧

1.2 高级单例模式

高级单例:高级单例故名思义就不会再像上面一样啦,不再是直接将一个对象赋值给命名空间,而是先执行一个自执行函数,在函数执行结束时返回一个对象

const person = (function () {
  function eat(food) {
    console.log(`I like eating ${food}`)
  }
  function hobby(h) {
    console.log(`I like playing ${h}`)
  }
  var account = '$10000000';
  var name = '王老五';
  var age = 40;
  return {
    name: name,
    age: age,
    eat: eat,
    hobby: hobby
  }
})();

2 工厂模式

function reg(name, age, sex) {
  var obj = {}; // 原材料
  obj.name = name; // 加工
  obj.age = age; // 加工
  obj.sex = sex; // 加工
  return obj; // 出厂
}

let s1 = reg('阿三', 19, 'boy');
let s2 = reg('李四', 18, 'girl');

console.log(s1 === s2); // false

工厂模式:像上面这样,把实现相同的函数封装成一个函数,当我们需要创建一个实例的时候,我们就执行这个函数即可,并且每个对象都是单例, 优势:高内聚,低耦合,提高代码的复用程度。

2.1 什么是高内聚 低耦合

高内聚: 就是相似度比较高的部分尽可能的集中在一起,不要分散,

低耦合: 就是两个相关的模块尽可能把依赖的部分降到最低,不要让两个系统产生强依赖。

高内聚低耦合是软件设计的基本原则,说的是程序的各个模块中,尽量让每个模块独立,相关的处理尽量在单个模块中完成,就是俗话说: 该干嘛干嘛去。

优点: 能降低各个模块之间的联系 减少牵一发而动全身 的概率 提高开发效率 降低维护成本 也便于单元测试 提高软件质量, 一般在中大项目做代码优化会用到这个原理

3 构造函数

构造函数模式: 通过 new 调用一个函数,此时这个函数不再是普通的函数 而是成为以恶搞类,函数名成为类名,而通过new调用,自动返回这个类的一个实例,在构造函数中,我们需要抽象这个类的属性和功能

function Teacher(name, age, subject, from) {
  this.name = name;
  this.mission = '处理问题';
  this.age = age;
  this.subject = subject;
  this.from = from;
  this.teach = function () {
    console.log(`${name} 解决 ${subject} 问题`);
  }
} // Teacher 是一个类,这里类型抽象了老师的属性,一个老师有的属性有姓名,年龄,教授学科,哪个学校的老师,以及老师会讲课的功能。

// 创建一个实例:DD
let mrMa = new Teacher('张三', 18, 'js', 'DD');
console.log(mrMa);
console.log(typeof mrMa); // object

// 通过浏览器控制台查看,这两个实例(对象)的前面出现了 Teacher,此时说明 mrMa 和 mrJiang 都属于 Teacher 类的实例。

4 发布订阅

发布订阅模式: 是模拟DOM2级事件池思想,在某一刻到来的时候,我们要做很多事(很多函数执行)。我们准备一个数组当做事件池, 并且提供向事件池中加入函数的方法以及移除的方法,当时刻来临时,我们把使劲啊池中的方法取出挨个执行。

订阅:订阅该时刻到来,把想做的事情加入事件池,  
发布:时刻真的到来了,把事件池中的方法都执行了
   // 准备事件池:
let ary = [];

function addListener(fn) {
if (ary.includes(fn)) return;
ary.push(fn)
}
function removeListener(fn) {
// 数组.filter 方法,把数组中满足条件的(回调函数返回true的项)组成一个新数组,原数组不变;
ary = ary.filter(item => item !== fn);
}
function fire() {
ary.forEach(item => item())
}

function fn1(_this) {
console.log(1)
}
function fn2() {
console.log(3)
}
function fn3() {
console.log(3)
}

// 订阅5s后的这个时刻
addListener(fn1);
addListener(fn2);
addListener(fn3);

// 取消订阅
removeListener(fn3);

setTimeout(function () {
// 5s后时刻来临,就把事件池中的方法都执行了
fire(this);
}, 5000);