js常见的设计模式一

  1.观察者模式

    定义一些一对多的关系,将一系列的观察者对目标函数感兴趣,将自己添加进目标函数,当目标函数状态发生改变时,发送通知,以此通知附加在目标上的观察者

/* 目标 */
class subject {
    constructor () {
        this.handlers = []
    }
    addhanler (fn) {
        this.handlers.push(fn)
    }
    notity () {
        this.handlers.forEach(hanlder=>{
            hanlder.update()
        })
    }
}
/* 观察者 */
class observer {
    constructor (name) {
        this.name = name
    }
    update () {
        console.log(this.name)
    }
}
let sub = new subject();

sub.addhanler(new observer('czklove'))
sub.addhanler(new observer('czklove1'))
sub.addhanler(new observer('czklove2'))

sub.notity()

  2.发布订阅者模式

    订阅者A和发布者B是通过中间件关联起来的,他们没有直接的交流

/* 
    pusher 为发布订阅者模式的中间件
    相对于观察者模式对了一个中间件,观察者模式,目标是观察者联系紧密
    而发布订阅者模式,发布者和订阅者完全没有关系
 */
let pusher = {
    clentlist: {},
    addhandler (key,fn) {
        if(!this.clentlist[key]) {
            this.clentlist[key] = []
        }
        this.clentlist[key].push(fn)
    },
    notify (key,...args) {
        if(this.clentlist[key]) {
            this.clentlist[key].forEach(hanlder=>{
                hanlder(...args)
            })
        }
    }
}
pusher.addhandler('click',(val)=>{
    console.log('1'+val)
})
pusher.addhandler('click',(val)=>{
    console.log('2'+val)
})
pusher.addhandler('click',(val)=>{
    console.log('3'+val)
})
pusher.notify('click','czklove')

  3.中间件模式

    中间件模式在js中也广泛引用,如node的express框架,axios源码中的请求拦截器和访问拦截器,我们实现一个简单的中间件

/* 中间件模式 */

class app {
    constructor () {
        this.hanlders = []
    }
    /* 使用use将需要执行的目标插入执行队列中 */
    use (fn) {
        this.hanlders.push(fn)
    }
    /* 开始执行入口 */
    run () {
        /* done为当前的执行函数
            如果已经执行进入了,则改为flase,
            查看回调hanlders是否会调用next,
            如果调用next则继续调用下一个回调函数
            如果没有next则执行到此为止
         */
        let done = true
        function next () {
            console.log('执行了next')
            done = true
        }
        /* 待执行的队列 */
        this.hanlders.forEach(hanlder => {
            if (!done) {
                return
            } else {
                done = false
                hanlder(next)
            }
        });
        if(done) {
            this.callback();
        }
    }
    /* 最终的回调执行函数 */
    callback () {
        console.log('我们最终需要执行的函数')
    }
}
let p = new app();

p.use(next=> {
    console.log('中间件1')
    next()
})
p.use(next=> {
    console.log('中间件2')
    next()
})
p.use(next=> {
    console.log('中间件3')
    next()
})
p.run()
(注,p传入的回调函数,next只是一个形参,不一定非要是next)

中间件1
执行了next
中间件2
执行了next
中间件3
执行了next
我们最终需要执行的函数

如果我们注释掉中间件2的next 则输出的结果为

中间件1
执行了next
中间件2

  4.单列模式

    对象在全局只有一个实列对象

    

/* 单列模式 */
/*  */
function createperson () {
    class person {
        constructor (name,age) {
            this.name = name;
            this.age = age;
        }
    }
    var person1 = null; 
    return function (name,age) {
        if (person) {  
        } else {
            person1 = new person(name,age)
        }
        return person1
    }

}
let creatp = createperson();

/* 创建person的实列对象p1 */
let p1 = creatp('czklove','28')
/* 创建person的实列对象p2 */
let p2 = creatp('czklove','29')
console.log(p1===p2)
/* 最终输出true */
/* person全局只能有一个实列对象 */

  5 工厂模式

    根绝不同的要求,生产出不同的实例对象

/* 工厂模式 */
/* 很简单,大概就是下面这个样子,根据传入的参数,生成对应的实例对象 */
function createobj (type) {
    function cj1 () {
        this.name = 'czklove',
        this.age = '17'
    }
    function cj2 () {
        this.name = 'czklove',
        this.age = '18'
    }
    function cj3 () {
        this.name = 'czklove',
        this.age = '19'
    }

    switch (type) {
        case 'cj1' :
            return new cj1();
        case 'cj2' :
            return new cj2();
        case 'cj3' :
            return new cj3();
        default:
            return new cj1();
    }
} 
console.log(createobj('cj1'))
console.log(createobj('cj2'))
console.log(createobj('cj3'))

//cj1

 //{name: "czklove", age: "17"}
   //{name: "czklove", age: "18"}
 
   //{name: "czklove", age: "19"}

  都是一些比较简单的模式,好多都用到了js中的闭包。好好理解闭包真的特别重要

posted @ 2019-05-23 21:03  waitklove  阅读(577)  评论(0编辑  收藏  举报