设计模式

一、设计模式的概念和介绍
1. 什么是设计模式
    - 经过大量验证,实验,总结,形成的一套固定的用来解决某类问题的方法
    - 是一套经过反复使用、多人知晓的、经过分类的、代码设计经验的总结
2. 有哪些设计模式:
    - 构造器模式,模块化模式,暴露模块模式,单例模式,中介者模式,原型模式,命令模式,外观模式,工厂模式,Mixin模式,装饰模式,亨元(Flyweight)模式,MVC模式,MVP模式,MVVM模式,组合模式,适配器模式,外观模式,观察者模式,迭代器模式,惰性初始模式,代理模式,建造者模式

 二、具体的设计模式讲解

1. 单例模式
    - 单个实例
    - 在面向对象方式编程时,经过多次操作,只有一个对象被创建,是单例模式
    - 多次new只有一个实例被创建
1.配合闭包实现单例模式:
        var Fn =(function(){
            var obj = {};
            return function(n){
                obj.name = n;
                obj.sex = 123;
                return obj;
            }
        })();
        var f1 = new Fn("admin");
        var f2 = new Fn("root");
        console.log(f1 === f2);
        console.log(Fn);
        console.log(f1);
        console.log(f2)
        2.配合当前的构造函数,将构造函数自身作为变量使用
        function Fn(n){
            Fn自身就是一个全局,函数也是变量,函数也可以作为对象使用
            if(!Fn._qfobj){
                Fn._qfobj = {};
            }
            Fn._qfobj.name = n;
            return Fn._qfobj;
        }
        var f1 = new Fn("admin");
        var f2 = new Fn("root");
        console.log(f1 === f2);
        console.log(Fn);
        console.log(f1);
        console.log(f2)
2. 组合模式
    - 组合对象
        - 将多个对象按照一定的规律组合,可以实现批量操作的功能
        - 简化了操作,但耗费了更多的性能,递归的思想
    - 使用场景
        - 组合模式,将对象组合成树状结构
        - DOM也是树状结构
  //构造独立的对象:
        //门:
        class GetHome{
            init(address){
                console.log(address+ "开门");

            }
        }
        //电脑:
        class Computer{
            init(address){
                console.log(address + "开电脑")
            }
        }
        //空调:
        class Air{
            init(address){
                console.log(address + "开空调");
            }
        }
        //组合器:
        class Combiner{
            constructor(address){
                this.address = address;
                this.arr = [];
            }
            add(o){
                this.arr.push(o);
            }
            init(){
                this.arr.forEach(ele =>{
                    ele.init(this.address);
                })
            }
        }
        //测试:
        //卧室的组合器:
        var bedroom = new Combiner("卧室");
        //2.组合卧室所需的设备:
        bedroom.add(new Computer);
        bedroom.add(new Air());
        // 3.通过卧室的组合器启动卧室的所有设备:
        bedroom.init();
        //客厅的组合器:
        var parlour = new Combiner("客厅");
        //2.组合客厅的设备:
        parlour.add(new GetHome());
        parlour.add(new Air());
        // 3.通过客厅的组合器启动客厅的所有设备:
        parlour.init();
        // 1.整个房子的组合器:
        var home = new Combiner();
        //2.组合客厅和卧室:
        home.add(bedroom);
        home.add(parlour);
        // 3.通过房子的组合器启动客厅和卧室:
        home.init();

 

 

3. 观察者模式
    - 发布订阅者模式
        - 发布者
            - 发布信息
        - 订阅者
            - 接收信息,根据信息内容作出对应的处理
    - 实现广播通信,一个发布者,多个接收者    
    - 订阅者的耦合非常低,可扩展能力非常强,可以随时加入或离开
    - 一对多的关系
class Headmaster{
            constructor(){
                //准备一个容器,用来存放将来可能发生的行为,状态:
                this.msg = {};
            }
            on(type,cb){//向容器中添加状态
                //判断是否是已存状态
                if(this.msg[type]){
                    this.msg[type].push(cb);//如果是已存状态,只添加处理功能
                }else{
                    this.msg[type] = [cb];//如果是未知状态,设置一个数组,保存处理功能
                }
            }
            off(type,cb){//用来删除容器中的状态:
            //删除之前先判断是否存在:
            if(!this.msg[type]) return;
            //如果存在,找到这个状态,找到要删除的处理功能:
            for(var i = 0;i<this.msg[type].length;i++){
                if(this.msg[type][i] === cb){
                    this.msg[type].splice(i,i);//删除
                    break;
                }
            }

            }
            emit(type){//用来模拟发布者状态
            //处理对应状态之前先判断是否存在:
            if(!this.msg[type]) return;
            this.msg[type].forEach(element =>{
                element();
            });

            }
        }
    var h = new Headmaster();
       //定义学员手册:
    h.on("抽烟",function(){
        console.log("罚款")
    });
    h.on("抽烟",function(){
        console.log("罚站");
    });
    h.on("喝酒",function(){
        console.log("叫家长");
    });
    h.on("烫头",function(){
        console.log("剃掉");
    });
    h.on("烫头", fn);
    function fn(){
        console.log("1");
    }
    console.log(h.msg);
    //删除其中一项的处理功能(可以删除掉的函数必须为有名函数:
    h.off("烫头",fn)
4. 拓展
    - 策略模式
        - 策略:计划,规划
        - 提前预置某些状态的处理功能,根据不同的状态决定哪个功能被调用

 

    - 适配器模式
        - 适配器,电源适配器:将不符合规范的内容,包装成符合规范的内容
 class Phone{
            constructor(){
                this.name = "手机"
            }
            call(){
                console.log("可以打电话")
            }
            game(){
                console.log("可以玩游戏")
            }
            song(){
                console.log("可以听歌")
            }
        }
        
        class Pad{
        constructor(){
            this.name = "平板"
        }
        game(){
            console.log("可以玩游戏")
        }
        song(){
            console.log("可以听歌")
        }
    }

    class Mp3{
        constructor(){
            this.name = "mp3"
        }
        song(){
            console.log("可以听歌")
        }
        book(){
            console.log("可以看电子书")
        }
    }

    function test(obj){
        if(obj.call){
            obj.call();
        }else{
            console.log(obj.name + "没有打电话功能")
        }
        if(obj.game){
            obj.game();
        }else{
            console.log(obj.name + "没有玩游戏功能");
        }
        if(obj.song){
            obj.song();
        }else{
            console.log(obj.name + "没有听歌功能");
        }
        if(obj.book){
            obj.book();
        }else{
            console.log(obj.name + "没有电子书功能");
        }
    }
    var phone = new Phone;
    test(phone);

 

    - 代理模式
        - 代理,快递员,代替某人完成某事
        - 代理系统的内置功能的执行,拦截数据,记录,或另做他用,或加工后使用
            - 功能A 调用了 功能B 时,有数据传递
                - 记录传递了什么数据
                - 将传递的数据做二次使用
                - 对传递的数据进行加工
    //定义功能A:
        class ModuleA{
        constructor(){
            this.name = "功能A"
        }
        send(obj,d){
            obj.getData(d)
        }
    }
    //定义功能B:
    class ModuleB{
        constructor(){
            this.name = "功能B";
        }
        getData(d){
            console.log("这是接收到的数据:" + d);
        }
    }
    //定义代理模块:
    class Agent{
        constructor(a,b){
            this.a =new a();
            this.b = new b();
        }
        send(d){
            //截获的数据
            this.d = d;
            this.a.send(this.b,d);
        }
        show(){
            console.log(this.d);
        }
    }
    var agent = new Agent(ModuleA,ModuleB);
    agent.send("你好");
    agent.show();

 

    - MVC模式
        - MVC原本是一种后台语言中的设计模式
        - M:module,模块层,管理的是数据
        - V:view,视图层,表现,呈现给用户的页面
        - C:control,控制器层,逻辑,用来处理逻辑,根据不同的指令,选择不同的数据,在不同的视图中呈现
        - 用户,调用控制器中的指令,控制器根据指令去取module层中的数据,暂存;再去view层中取出对应的视图,将数据发给视图,由视图做渲染
//定义控制层的属性和方法:
        class Control{
            constructor(){
                this.m = new Module();
                this.v = new View();
            }
            task1(){
                var d = this. m.data1();
                this.v.page2(d);
            }
            task2(){
            var d = this.m.data3();
            this.v.page1(d);
        }
    }
    //定义模块层:
    class Module{
        data1(){
            return "hello";
        }
        data2(){
            return "world";
        }
        data3(){
            return "123";
        }
    }
    //定义视图层:
    class View{
        page1(d){
            console.log(d);
        }
        page2(d){
            alert(d);
        }
        page3(d){
            document.write(d);
        }
    }

    var c = new Control();
    c.task1();
    c.task2();
    - 工厂模式:
        function Create(n, s, a){
            var obj = {};
            obj.name = n;
            obj.sex = s;
            obj.age = a;
            return obj;
        }
        var o1 = Create("admin","1",17);
        var o2 = Create("admin","1",17);
        var o3 = Create("admin","1",17);

 

 

posted @ 2020-06-03 21:25  油画家的第一站  阅读(142)  评论(0编辑  收藏  举报