关于设计模式

什么是设计模式?

针对特定的问题,给出简介而优化的方案,在特点的情况,特定的时期,针对特点的问题使用的。

单例模式?

在何种情况下会使用单例模式呢?
当你想要一个构造函数,一辈子只能new一个对象的时候使用
使用场景:
每个网页有肯定要有很多弹出框,如果不使用单例模式的话,每new就是创造一个div,这样会导致代码冗余和内存溢出,如果使用单例模式,每次new的都是第一次div,只是文字内容改变了。

核心代码:

var Person = (function fn(){
    function Student(){
        this.name = "pcy"
    }
    Student.prototype.say = function(){console.log("hello world")}
    let instance = null
    return function fn1(){
        return !instance? instance = new Student() : instance
    }
})() 

let p = new Person()  
let p1 = new Person()
console.log(p);//Student {name: "pcy"}
console.log(p1);//Student {name: "pcy"}
console.log(p === p1);//true
p.say()//hello  world
p1.say()//hello world

我们来分析一下:
正常情况下,console.log(p === p1)应该返回false,但是如果我们使用单例模式,他们就返回true,因为他们new的都是同一个对象,使用自执行函数,是为了延长instance的生命周期,Person的是fn函数执行以后的返回值,即fn1函数,fn1第一次执行会得到一个实例,以后的每一次执行得到的都是第一次的时候,里面的逻辑就是判断他有没有instance,如果没有的话就返回他一个实例,赋值给instance,有的话就返回instance,即那个实例,所以每次new的都是同一个实例。

组合模式

什么是组合模式?
把多个对象组成树状结构来表示局部与整体,使得用户可以同时操作单个对象和对象的组合。

使用场景:
比如一个页面中,有一个轮播图,你切换页面了,轮播图的dom已经不动了,但是定时器还在动,所以我们需要关闭定时器,但是一个页面肯定不止一个轮播图,我们不可能给每个轮播图都关闭定时器,这个时候我们就可以给他们设一个总开关,去控制他们。这就是组合模式的使用场景

实现组合模式方式:
有若干个启动方式一样的构造函数,我们准备一个总开关,只要总开关一启动,这些构造函数都启动
+ 需要一个承载所有构造函数的实例数组
+ 需要一个方法,向数组里面添加内容
+ 需要一个方法,把所有数组里面的内容启动了

代码实现:

class Play{
    constructor(){}
    init(){
        console.log("我在打游戏");
    }
}

class Sleep{
    constructor(){}
    init(){
        console.log("我在睡觉");
    }
}

class Eat{
    constructor(){}
    init(){
        console.log("我在吃饭")
    }
}

class Compose{
    constructor(){
        this.arr = []
    }
    add(instance){
        this.arr.push(instance)
    }
    init(){
        console.log("总开关启动了");
        this.arr.forEach(item=>item.init())
    }
}
//masteroff就是总开关
let masteroff = new Compose()
//每次执行添加方法 就往总开关上加内容
masteroff.add(new Sleep())
masteroff.add(new Eat())
masteroff.add(new Play())
//只要总开关启动,里面的构造函数就启动了
masteroff.init()  //====>   总开关启动了
                        // 开始玩游戏了
                        // 开始吃东西
                        // 开始睡觉

观察者模式

什么是观察者模式?
观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯

使用场景:
vue

案例:初中班主任就是观察者,我们自己就是被观察者,对于观察者:当被观察者的状态被改变了,他们就会触发技能,请家长,对于被观察者:我们的状态就应该是学习,当我们状态发生改变,就会立马通知正在观察里的人,触发技能

代码实现

class Student{
    constructor(){
        //定义初始状态
        this.state="好好学习"
        this.observers=[]//放观察者的,将来如果状态改变,就会通知这个数组里的人,触发技能
    }
    //改变自己的状态
    setState(value){
        this.state = value
        this.notify()
    }
    //获取自己的状态
    getState(){
        return this.state
    }
    //添加观察者
    add(observer){
        this.observers.push(observer)
    }
    //通知观察者,状态改变了,触发技能
    notify(){
        this.observers.forEach(item=>{item.qingjiazhang(this.state)})
    }
}

class Observer{
    constructor(name){
        this.name = name
    }
    qingjiazhang(state){
        console.log(`我是${this.name},因为你${state}了,所以明天叫家长来学学校`);
    }
}
//创建一个被观察的实例
let xiaoming = new Student()
//创建三个观察者的实例
let banzhuren = new Observer("班主任")
let nianjizhuren = new Observer("年纪主任")
let xiaozhang = new Observer("校长")

//让班主任 年纪主任 观察者小明
xiaoming.add(banzhuren)
xiaoming.add(nianjizhuren)

//改变小明的状态
xiaoming.setState("玩手机")

来分析一下:
让班主任和年纪主任观察者小明,(通过小明.add方法添加观察者)当小明的状态从好好学习变成,玩手机,就触发notify方法,遍历观察者数组,触发观察者的请家长技能,把改变的状态传递下去,最后打印
在这里插入图片描述

订阅 发布模式

什么是订阅 发布 模式?
定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。

使用场景:
addEventListener(click,fn)

理解订阅 发布模式:
我去书店买书,管理员告诉我这个书要过几天才出版,我说好的到了电话通知我一下,这里我就订阅了,当出版社出版书的时候,管理员就会打电话告诉我书到了你可以来买书了。这里就是出版社发布了,管理员知道了告诉我。 我向管理员订阅了这本书,当出版社发布的时候,和管理员才会告诉我书到了

实现方式:
1.消息盒子{}
=>click:[fn1,fn2,fn3]
=>mouseover:[fn4,fn5,fn6]
2.订阅的方法
=>向消息盒子里面添加内容
3.取消订阅的方法
=>把已经订阅的方法,从消息盒子内部拿走
4.发布事件的方法
=>把消息盒子里面的对应的处理函数执行了

代码实现

class Observer{
    constructor(){
        this.message={}
    }
    //订阅的方法
    on(type,fn){//type 类型    fn:事件处理函数    
        if(!this.message[type]){//如果message对象里没有这个,就新建一个数组
            this.message[type] = []
        }
        this.message[type].push(fn)//如果没有就新建一个数组,事件处理函数加进去
    }
    //取消订阅的方法
    delete(type,fn){
        //如果消息中心为空,就直接返回,不然的话就过滤数组,item和fn不一样的
        if(!this.message[type]) return
        this.message[type] = this.message[type].filter(item => item !== fn)
    }
    //发布的方法
    out(type,...arg){
        //判断有没有定位过,没有订阅过直接跳过
        if(!this.message[type]) return
        var event = {
            type:type,
            data:arg
        }
        this.message[type].forEach(item => item(event))
    }
}

let p = new Observer()
//订阅事件
p.on('click',handlerA)
p.on('click',handlerB)
p.on('click',handlerC)

//取消订阅事件
p.delete('click',handlerA)

//发布事件
p.out('click','hello world',true,{name:'jack'})
//准备几个事件处理函数
function handlerA(e){console.log('我是事件处理函数,handerA',e)}
function handlerB(e){console.log('我是事件处理函数,handerB',e)}
function handlerC(e){console.log('我是事件处理函数,handerC',e)}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值