theme: channing-cyan
我们学习设计模式步骤应该是先理解其中的思想,合理使用设计模式,总结经验,融会贯通。
发布订阅模式
对象间的一种一对多的依赖关系,当一个对象发生状态改变的时候,其他所有依赖于它所有的对象都将得到通知。
我们可以用选择省份城市县区的多级联动模块来理解它。
代码语言:javascript复制 // 发布订阅模式
class Pubsub{
constructor() {
this.subsrcibers = {};
}
// 订阅
subscribe(type,fn) {
let listeners = this.subsrcibers[type] || [];
listeners.push(fn);
}
// 取消订阅
unsubscribe(type,fn) {
let listeners = this.subsrcibers[type];
if(!listeners || !listeners.length) return;
this.subsrcibers[type] = listeners.filter((v) => v !== fn);
}
// 触法订阅事件
publish(type,...args){
let listeners = this.subsrcibers[type];
if(!listeners || !listeners.length) return;
listeners.forEach((fn) => fn(...args));
}
}
let ob = new Pubsub();
ob.subscribe("add",(val) => console.log(val));
ob.publish("add",1);
命令模式
执行默写特定事情的指令, 命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
就是我们在将一个请求封装成一个对象,发送不同的请求和参数,让它执行功能,这样的好处就是解耦。
代码语言:javascript复制 // 命令模式
// 设置命令
const setCommand = (button,command) =>{
button.onclick = ()=>{
command.execute();
}
}
// 业务逻辑写这里
const MenuBar = {
refresh: () => {
console.log("refresh","jackson");
}
}
const RefreshMenBarCommand = (receiver) =>{
return{
execute: () =>{
receiver.refresh();
}
}
}
const refreshMenBarCommand = new RefreshMenBarCommand(MenuBar);
// 设置绑定按钮和指令
setCommand(refreshButton,refreshMenBarCommand);
组合模式
用小的对象来构造更大的对象,就是把一些小的对象,组合到一个大的对象中,相当于给树干添加树枝一样,一般用来表示 部分->整体 的层次结构。 从is-a到has-a
代码语言:javascript复制 // 组合模式
class MacroCommand{
constructor(){
this.commands = [];
}
// 添加子对象逻辑
add(command){
console.log(this);
this.commands.push(command);
}
// 执行父对象逻辑
execute(){
for(let i = 0; i < this.commands.length; i ){
this.commands[i].execute();
}
}
}
const macroCommand = new MacroCommand();
const name1Command = {
execute:() =>{
console.log('jackson');
}
}
const name2Command = {
execute:() =>{
console.log('bear');
}
}
macroCommand.add(name1Command);
macroCommand.add(name2Command);
macroCommand.execute();
装饰器模式
在不改变自身对象的基础上,在程序运行期间给对象动态的添加职责。
适配器模式
主要解决俩个软件间的接口不兼容问题,不需要改变已有的接口,就能使他们协同作用。
使用前
我们这里是没有使用适配器,这样东西比较少,我们看起来也挺清晰的,但是如果有很多的话需要一直if else判断。改造一下
代码语言:javascript复制 // 适配器模式
const aMap = {
show:() => {
console.log('a地图渲染')
}
}
const bMap = {
display:() => {
console.log('b地图渲染')
}
}
// 添加适配器
const bMapAdapter = {
show:() => {
return bMap.display();
}
}
const renderMap = (map) => {
if (map.show instanceof Function){
map.show();
}
}
renderMap(aMap);
renderMap(bMapAdapter); //这里不是传参bMap 而是适配器
我们在中间加一层适配器,就可以不用做那么多if else判断了,逻辑清晰,而且不需要修改底层的接口逻辑。
总结
在使用设计模式的时候不能滥用设计模式,设计模式有20多种,都是前辈们几十年来总结下来的,在日常开发中,我们也应该注意设计模式的原理,多思考,从而写出优雅而又高效的代码。 往期回顾: 【青训营】关于JS设计模式(一) - 掘金 (juejin.cn)