JavaScript中几种常用的设计模式

2022-09-07 17:13:28 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

设计模式:代码书写经验,为了应对各种场景,经过前人不断的总结,压缩,形成的一套又一套的代码的书写规范,形成了设计模式。

1.单例模式

单例模式是一种常用的设计模式,如果需要多次创建同一个对象,完成同一件事情,就会多次new出来很多个对象,而单例模式确保只有一个实例,并提供全局访问。

代码语言:javascript复制
var f = (function(){
        var instance;
        return function(){
            if(!instance){
            // 如果没有则赋值,初始化
                instance = new Person();
            }
             // 有的话直接返回
            return instance;
        }
    })();

    var p1 = f();
    var p2 = f();

    console.log(p1);
    console.log(p2);
    // 单例模式(唯一的),每次获取的都是一个东西,所以他
    两相等
    console.log(p1 === p2);

2.组合模式

组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。将多个对象的功能,组成起来,实现批量执行。使用这种模式可以用一条命令在多个对象上激发复杂的递归的行为。

代码语言:javascript复制
// 先准备一些需要批量执行的功能
    class GoHome{
        init(){
            console.log("到家了,开门");
        }
    }
    class OpenComputer{
        init(){
            console.log("开电脑");
        }
    }
    class OpenXiaoAi{
        init(){
            console.log("开音乐");
        }
    }

    // 组合器,用来组合功能
    class Comb{
        constructor(){
            // 准备容器,用来防止将来组合起来的功能
            this.skills = [];
        }
        // 用来组合的功能,接收要组合的对象
        add(task){
            // 向容器中填入,将来准备批量使用的对象
            this.skills.push(task);
        }
        // 用来批量执行的功能
        action(){
            // 拿到容器中所有的对象,才能批量执行
            this.skills.forEach( val => {
                val.init();
            } );
        }
    }

    // 创建一个组合器
    var c = new Comb();

    // 提前将,将来要批量操作的对象,组合起来
    c.add( new GoHome() );
    c.add( new OpenComputer() );
    c.add( new OpenXiaoAi() );

    // 等待合适的时机,执行组合器的启动功能
    c.action();
    // 在内部,会自动执行所有已经组合起来的对象的功能

3.观察者模式

也称发布-订阅模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,就会通知所有的观察者对象。发布者:发布信息,会随时更新自身的信息或状态。 订阅者:接收信息,接收到发布者发布的信息,从而做出对应的改变或执行,订阅者可以随时加入或离开。

代码语言:javascript复制
// 需要一个观察者,创建一个事件容器,并准备on等方法
    function Observer(){
        this.msg = {};
    }
    // 向事件容器中添加事件,消息
    Observer.prototype.on = function(type, cb){
        // 判断事件容器中,有没有当前传进来的这个类型
        // 如何没有,走else
        if(this.msg[type]){
            // 如果有,直接给第一次设置的这个数组,添加个新数据
            this.msg[type].push(cb);
        }else{
            // 给他设置一个对应的属性,同时,属性值需要提前写成数组
            this.msg[type] = [cb];
        }
    }
    Observer.prototype.emit = function(type){
        // 首先判断事件容器中是不是已经记录
        if(this.msg[type]){
            var event = {
                type:type
            }
            // 如果已经记录了信息,那么就去执行这个消息对应的所有的处理函数
            this.msg[type].forEach(val=>{
                val.call(this,event);
            })
        }
    }
    Observer.prototype.off = function(type, cb){
        // 首先判断事件容器中是不是已经记录
        if(this.msg[type]){
            // 准备保存符合传参的处理函数的索引
            var i = 0;
            // 遍历,判断,当前类型对应的每一个处理函数,依次作比较
            var onoff = this.msg[type].some((val, idx)=>{
                i = idx;
                return val === cb;
            })
            // 判断是否获取到重复的函数
            if(onoff){
                // 如果有,那么就在当前的消息处理函数的队列中,删除这个函数
                this.msg[type].splice(i, 1);
            }
        }
    }

    // 首先创建一个观察者对象
    var ob = new Observer();
    // 准备两个处理函数
    function a(){
        console.log("没收");
    }
    function b(){
        console.log("叫家长");
    }

    // 随便绑定一个消息,给了两个处理函数
    ob.on("玩手机",a);
    ob.on("玩手机",b);

    // 模拟事件的执行
    ob.emit("玩手机");

    // 删除一个处理函数
    ob.off("玩手机", b);

    // 模拟事件的执行
    ob.emit("玩手机");

4.MVC模式

MVC模式是一种架构模式,它将应用抽象为3个部分:M:model数据(模型);V:view视图;C:控制器

代码语言:javascript复制
// 创建模型,管理多个数据
    class Model{
        model1(){
            return "hello";
        }
        model2(){
            return "world";
        }
        model3(){
            return "你好";
        }
    }

    // 创建视图,管理多种渲染方式
    class View{
        view1(data){
            console.log(data);
        }
        view2(data){
            document.write(data);
        }
        view3(data){
            alert(data);
        }
    }

    // 创建控制器,设定对应的指令
    class Ctrl{
        constructor(){
            // 初始化模型和视图
            this.m = new Model();
            this.v = new View();
        }
        // 在指令中,可以读取对应的数据,放在对应的视图中
        ctrl1(){
            var data = this.m.model1();
            this.v.view1(data);
        }
        ctrl2(){
            var data = this.m.model2();
            this.v.view3(data);
        }
    }

    var c = new Ctrl();
    c.ctrl1();
    c.ctrl2();

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/154270.html原文链接:https://javaforall.cn

0 人点赞