【青训营】关于JS设计模式(二)

2022-11-14 16:52:01 浏览数 (1)


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)

0 人点赞