设计模式 —— 关于8月份学习设计模式的总结

设计模式 —— 关于8月份设计模式的总结

《工欲善其事,必先利其器》

设计模式 —— 关于8月份学习设计模式的总结_第1张图片

每到月底,都会对自己本月学习的知识进行一个复习。目的是为了巩固旧知识,防止忘记,顺便也起到一个总结的作用。今天需要复习的内容是 —— 《JavaScript 的设计模式》

复习一:观察者模式

复习一下观察者模式,分四步走,分别是定义类或方法(愿意用ES5实现的小伙伴也可以试一下,都是一样的~),然后实例化两者,再触摸被观察者,接着给观察者反馈,最后取消观察并总结。

  1. 定义观察者和被观察者对象
class Observe {
	constructor(name) {
		this.name = name;
	}
	update(model) {
		console.log(model.name +" tells " + this.name + " I want to go " + model.state);
	}
}
class Subject {
	constructor(name) {
		this.name = name;
		this.subs = [];
		this.state = "study";
	}
	patch(observer) {
		this.subs.push(observer);
		return this.subs.length - 1;
	}
	rePatch(state) {
		this.state = state;
		if (this.subs.length > 0) {
			this.subs.forEach(item => {
				item.update(this);
			})
		} else {
			console.log("Please initzalition Observers!");
		}
	}
	cancelPatch(index) {
		if (this.subs.length > 0) {
			this.subs.splice(index, 1);
		} else {
			console.log("None Observers!");
		}
	}
}
  1. 实例化并观察者触摸被观察者
const father = new Observer("father");
const mother = new Observer("mother");
const son = new Subject("son");

// 触摸
const fatherKey = son.patch(father);
const motherKey = son.patch(mother);
  1. 被观察者反馈,并取消观察
son.rePatch("swimming!");

// son tells father I want to go swimming!
// son tells mother I want to go swimming!

// cancel
son.cancelPatch(motherKey);

son.rePatch("fishing!");
// son tells father I want to go fishing!
  1. 总结

观察者模式 其实非常简单,它并不像其他设计模式那样复杂,但实际上在一个日常的开发中或者开源框架和库的源码中,处处都有它的身影。虽说简单,但实用且常用,是需要我们每一个开发人员都要牢记的一种 设计模式

复习二:发布订阅模式

设计模式 —— 关于8月份学习设计模式的总结_第2张图片

发布订阅模式,发布者和订阅者是间接的关系。他们之间其实是一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知,前提必须是,订阅者和发布者任何一方触发了同一个主题。本质上,发布者是否发布,订阅者是无感的(完全解耦)。只有发布者发布的内容是订阅者订阅的主题,订阅者才会收到通知。

观察者模式 ,观察者和被观察者之间是直接的关系,被观察者的变化都会影响或通知到另外一方。从上图看,我们可以认为:

  • 观察者模式包含着发布订阅模式
  • 两者都拥有通知客户的能力,发布订阅模式由调度中心分配,没有直接关联,相当于观察者模式的升级版
  • 观察者模式主体在发生事件时与客体是松解耦的,不需要感知到客体具体的行为,进行统一的update,但主体还是需要感知到客体的存在,初始化时要预先attach到观察者。发布订阅模式主体不需要感知到客体的任何行为或存在,主体和客体通过事件关联,解耦性更强

也是分2步走,先实现一个经典的 EventBus,然后进行实例测试:

  1. 实现 EventBus
class Events {
	constructor() {
		this.eventId = 0;
		this.eventLine = {};
	}
	$on(eventName, handler) {
		this.eventId++;
		if (!this.eventLine.hasOwnProperty(eventName)) this.eventLine[eventName] = {};
		this.eventLine[eventName][this.eventId] = handler;
		console.log(eventName + "新增了一位粉丝!!");
		return this.eventId;
	}
	$emit(eventName, ...args) {
		if (this.errorEventCaptured(eventName)) return console.log("Before $emit you need to $on events!");
		for(const id in this.eventLine[eventName]) {
			this.eventLine[eventName][id](...args);
		}
	}
	$off(eventName, key) {
		if (this.errorEventCaptured(eventName)) return console.log("Before $off you need to $on events!");
		if (!Object.keys(this.eventLine[eventName]).length) delete this.eventLine[eventName];
		delete this.eventLine[eventName][key];
		console.log("一位粉丝取消了关注");
	}
	errorEventCaptured(eventName) {
		const eventHandlers = this.eventLine[eventName];
		return eventHandlers == undefined ? true : false;
	}
}
  1. 实例化测试
const eventBus = new Events;
// 关注
const key1 = eventBus.$on("vk哥", (articleName) => {
    // 张三关注了你,有发布新文章请通知它
    console.log("vk哥发布新文章了!!—— 《" + articleName + "》,通知了张三。");
})
const key2 = eventBus.$on("vk哥", (articleName) => {
    // 李四关注了你,有发布新文章请通知它
    console.log("vk哥发布新文章了!!—— 《" + articleName + "》,通知了李四。");
})
// 发布
eventBus.$emit("vk哥", "设计模式——发布订阅模式");
// 李四取消了关注
eventBus.$off("vk哥", key2);
// 取消关注后再次发布
eventBus.$emit("vk哥", "Vue2.0源码剖析");

看一下效果先:

设计模式 —— 关于8月份学习设计模式的总结_第3张图片

  1. 总结

发布订阅模式是观察者模式的升级版,这在我们开发中是经常会运用到的一种思想,发布者和订阅者通过同一个主题,也就是 “vk哥”,来绑定关系的。换句话说,发布者是否发布与订阅者是否订阅,没有直接的关联,实现了完全性的解耦。

关于本篇文章,代码我全都上传至码云了,需要的小伙伴自行下载 —— 《下载地址》。

最后,感谢你的阅读,愿你的未来一片光明。

你可能感兴趣的:(设计模式,javascript,设计模式,学习,javascript)