坚持周总结系列第七周(2020.5.29) JS设计模式

JS设计模式

单例模式

单例模式:保证一个类仅有一个实例,并提供访问他的全局访问点。

var getSingle=function(fn){
     
    var result
    return function(){
     
        return result || (result = fn.apply(this,arguments))
    }
}

策略模式

策略模式:定义一系列的算法,把它们一个个封装起来,并且使他们可以互相替换。

var strategies={
     
    'S':function(salary){
     
        return salary*4
    },
    'A':function(salary){
     
        return salary*3
    },
    'B':function(salary){
     
        return salary*2
    }
}
var calculateBouns=function(level,salary){
     
    return strategies[level](salary)
}
console.log(calculateBouns('S',10000))

代理模式

代理模式:为一个对象提供一个代用品或者占位符,以便控制对它的访问。

var myImage=(function(){
     
    var imgNode=document.createElement('img')
    document.body.appendChild(imgNode)
    return {
     
        setSrc:function(src){
     
            imgNode.src=src
        }
    }
})()
var proxyImage=(function(){
     
    var img=new Image
    img.onload=function(){
     
        myImage.setSrc(this.src)
    }
    return {
     
        setSrc:function(src){
     
            myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif')
            img.src=src
        }
    }
})()
proxyImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg')

迭代器模式

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。

var getActiveUploadObj=function(){
     
    try{
     
        return new ActiveXObject('TXFTNActiveX.FTNUpload')// IE上传控件
    }catch(e){
     
        return false
    }
}
var getFlashUploadObj=function(){
     
    if(supportFlash()){
     
        var str=''
        return $(str).appendTo($('body'))
    }
    return false
}
var getFormUploadObj=function(){
     
    var str=''; // 表单上传
    return $(str).appendTo($('body'))
}
// 迭代器
var iteratorUploadObj=function(){
     
    for(var i=0,fn;fn=arguments[i++];){
     
        var uploadObj=fn()
        if(uploadObj!==false){
     
            return uploadObj
        }
    }
}
var uploadObj=iteratorUploadObj(getActiveUploadObj,getFlashUploadObj,iteratorUploadObj)

发布订阅模式

发布订阅模式:又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

$.ajax('http:// xxx.com?login',function(data){
     // 登陆成功
    login.trigger('loginSucc',data)// 发布登陆成功的消息    
})
// 各模块监听登陆成功的消息
var header=(function(){
     
    login.listen('loginSucc',function(data){
     
        header.setAvatar(data.avatar)
    })
    return {
     
        setAvatar:function(data){
     
            console.log('设置header模块的头像')
        }
    }
})()
var nav=(function(){
     
    login.listen('loginSucc',function(data){
     
        nav.setAvatar(data.avatar)
    })
    return {
     
        setAvatar:function(avatar){
     
            console.log('设置nav模块的头像')
        }
    }
})()

命令模式

命令模式:命令模式中的命令指的是一个执行某些特定事情的指令。

var setCommand=function(button,func){
     
    button.onclick=function(){
     
        func()
    }
}
var MenuBar={
     
    refresh:function(){
     
        console.log('刷新菜单界面')
    }
}
var SubMenu={
     
    add:function(){
     
        console.log('增加子菜单')
    },
    del:function(){
     
        console.log('删除子菜单')
    }
}
var RefreshMenuCommand=function(reciver){
     
    return function(){
     
        reciver.refresh()
    }
}
var AddSubMenuCommand=function(reciver){
     
    return function(){
     
        reciver.add()
    }
}
var DelSubMenuCommand=function(reciver){
     
    return function(){
     
        reciver.del()
    }
}
var refreshMenuCommand=RefreshMenuCommand(MenuBar)
var addSubMenuCommand=AddSubMenuCommand(SubMenu)
var delSubMenuCommand=DelSubMenuCommand(SubMenu)
setCommand(button1,refreshMenuCommand)
setCommand(button2,addSubMenuCommand)
setCommand(button3,delSubMenuCommand)

组合模式

组合模式:将对象组合成树形结构,以表示 “部分—整体” 的层次结构。

var Floder=function(name){
     
    this.name=name
    this.files=[]
}
Floder.prototype.add=function(file){
     
    this.files.push(file)
}
Floder.prototype.scan=function(){
     
    console.log('开始扫描文件夹:'+this.name)
    for(var i=0,file,files=this.files;file=files[i++];){
     
        file.scan()
    }
}
var File=function(name){
     
    this.name=name
}
File.prototype.add=function(){
     
    throw new Error('文件下面不能在添加文件')
}
File.prototype.scan=function(){
     
    console.log('开始扫面文件:'+this.name)
}
// 实例测试
var floder=new Floder('学习资料')
var floder1=new Floder('JavaScript')
var floder2=new Floder('jQuery')

var file1=new File('JavaScript设计模式与开发实践')
var file2=new File('精通jQuery')
var file3=new File('重构与模式')

floder1.add(file1)
floder2.add(file2)

floder.add(floder1)
floder.add(floder2)
floder.add(file3)

模板方法模式

模板方法模式:由两部分结构组成,第一部分是抽象父类,第二部分是具体实现的子类。

var Beverage=function(){
     }
Beverage.prototype.boilWater=function(){
     
    console.log('把水煮沸')
}
Beverage.prototype.brew=function(){
     }
Beverage.prototype.pourInCup=function(){
     }
Beverage.prototype.addCondiments=function(){
     }
Beverage.prototype.init=function(){
     
    this.boilWater()
    this.brew()
    this.addCondiments()
}
// 创建Coffee类
var Coffee=function(){
     }
Coffee.prototype=new Beverage()
Coffee.prototype.brew=function(){
     
    console.log('用沸水冲泡咖啡')    
}
Coffee.prototype.pourInCup=function(){
     
    console.log('把咖啡倒进被子')
}
Coffee.prototype.addCondiments=function(){
     
    console.log('加糖和牛奶')
}
var coffee=new Coffee()
coffee.init()
// 创建Tea类
var Tea=function(){
     }
Tea.prototype=new Beverage()
Tea.prototype.brew=function(){
     
    console.log('用沸水浸泡茶叶')
}
Tea.prototype.pourInCup=function(){
     
    console.log('把茶倒进杯子')
}
Tea.prototype.addCondiments=function(){
     
    console.log('加柠檬')
}
var tea=new Tea()
tea.init()

享元模式

享元模式:运用共享技术来有效支持大量细粒度的对象。

var Model=function(sex){
     
    this.sex=sex
}
Model.prototype.takePhoto=function(){
     
    console.log('sex='+this.sex+' underwear='+this.underwear)
}
// 分别创建男模特和女模特
var maleModel=new Model('male')
var femalModel=new Model('female')
// 给男模依次穿上所有男装,拍照
for(var i=1;i<=50;i++){
     
    maleModel.underwear='underwear'+i
    maleModel.takePhoto()
}
// 给女模依次穿上所有女装,拍照
for(var i=1;i<=50;i++){
     
    femaleModel.underwear='underwear'+i
    femaleModel.takePhoto()
}

职责链模式

职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。

var order500=function(orderType,pay,stock){
     
    if(orderType===1 && pay===true){
     
        console.log('500元定金预购,得到100元优惠券')
    }else{
     
        return 'next'
    }
}
var order200=function(orderType,pay,stock){
     
    if(orderType===2 && pay===true){
     
        console.log('200元定金预购,得到50元优惠券')
    }else{
     
        return 'next'
    }
}
var orderNormal=function(orderType,pay,stock){
     
    if(stock>0){
     
        console.log('普通购买,无优惠券')
    }else{
     
        console.log('手机库存不足')
    }
}
var Chain=function(fn){
     
    this.fn=fn
    this.successor=null
}
Chain.prototype.setNext=function(successor){
     
    return this.successor=successor
}
Chain.prototype.passRequest=function(){
     
    var ret=this.fn.apply(this,arguments)
    if(ret==='next'){
     
        return this.successor && this.successor.passRequest.apply(this.successor,arguments)
    }
    return ret
}
var chainOrder500=new Chain(order500)
var chainOrder200=new Chain(order200)
var chainOrderNormal=new Chain(orderNormal)
chainOrder500.setNext(chainOrder200)
chainOrder200.setNext(chainOrderNormal)
// 测试
chainOrder500.passRequest(1,true,500)// 输出:500 元定金预购,得到 100 优惠券
chainOrder500.passRequest(2,true,500)// 输出:200 元定金预购,得到 50 优惠券
chainOrder500.passRequest(3,true,500)// 输出:普通购买,无优惠券
chainOrder500.passRequest(1,false,0)// 输出:手机库存不足

中介者模式

中介者模式:解除对象与对象之间的紧耦合关系。

var goods={
     
    'red|32G':3,
    'red|16G':0,
    'blue|32G':1,
    'blue|16G':6
}
// 中介者
var mediator=(function(){
     
    var colorSelect=document.getElementById('colorSelect'),
      memorySelect=document.getElementById('memorySelect'),
      numberInput=document.getElementById('numberInput'),
      colorInfo=document.getElementById('colorInfo'),
      memoryInfo=document.getElementById('memoryInfo'),
      numberInfo=document.getElementById('numberInfo'),
      nextBtn=document.getElementById('nextBtn')
    return {
     
        changed:function(obj){
     
            var color=colorSelect.value,
                memory=memorySelect.value,
                number=numberInput.value,
                stock=goods[color+'|'+memory]
            if(obj===colorSelect){
     
                colorInfo.innerHTML=color
            }else if(obj===memorySelect){
     
                memoryInfo.innerHTML=memory
            }else if(obj===numberInput){
     
                numberInfo.innerHTML=number
            }
            if(!color){
     
                nextBtn.disabled=true
                nextBtn.innerHTML='请选择手机颜色'
                return
            }
            if(!memory){
     
                nextBtn.disabled=true
                nextBtn.innerHTML='请选择内存大小'
                return
            }
            if(((number-0)|0) !== number-0){
     
                nextBtn.disabled=true
                nextBtn.innerHTML='请输入正确的购买数量'
                return
            }
            nextBtn.disabled=false
            nextBtn.innerHTML='放入购物车'
        }
    }
    
})()
// 测试
colorSelect.onchange=function(){
     
    mediator.change(this)
}
memorySelect.onchange=function(){
     
    mediator.change(this)
}

装饰者模式

装饰者模式:动态的给某个对象添加一些额外的职责,而不会影响这个类派生的其他对象。

var plane={
     
    fire:function(){
     
        console.log('发射普通子弹')
    }
}
var missileDecorator=function(){
     
    console.log('发射导弹')
}
var atomDecorator=function(){
     
    console.log('发射原子弹')
}

var fire1=plane.fire
plane.fire=function(){
     
    fire1()
    missileDecorator()
}
var fire2=plane.fire
plane.fire=function(){
     
    fire2()
    atomDecorator()
}

plane.fire()// 分别输出: 发射普通子弹、发射导弹、发射原子弹

状态模式

状态模式:关键是区分事物内部的状态,事物内部状态的改变往往会带来事物行为的改变。

var Light=function(){
     
    this.currState=FSM.off// 设置当前状态
    this.button=null
}
Light.prototype.init=function(){
     
    var button=document.createElement('button'),
        self=this
    button.innHTML='已关灯'
    this.button=document.body.appendChild(button)
    this.button.onclick=function(){
     
        self.currState.buttonWasPressed.call(self)// 把请求委托给FSM状态机
    }
}
var FSM={
     
    off:{
     
        buttonWasPressed:function(){
     
            console.log('关灯')
            this.button.innerHTML='下一次按我就是开灯'
            this.currState=FSM.on// 状态切换
        }
    },
    on:{
     
        buttonWasPressed:function(){
     
            console.log('开灯')
            this.button.innerHTML='下一次按我就是关灯'
            this.currState=FSM.off// 状态切换
        }
    }
}
var light=new Light()
light.init()

适配器模式

适配器模式:适配器模式的作用是解决两个软件实体之间的接口不兼容的问题。使用适配器模式之后,原本由于接口不兼容而不能工作的两个软件实体可以一起工作。

var googleMap={
     
    show:function(){
     
        console.log('开始渲染谷歌地图')
    }
}
var baiduMap={
     
    dispaly:function(){
     
        console.log('开始渲染百度地图')
    }
}
var renderMap=function(map){
     
    if(map.show instanceof Function){
     
        map.show()
    }
}
// 百度地图适配器
var baiduMapAdapter={
     
    show:function(){
     
        return baiduMap.display()
    }
}
// 测试
renderMap(googleMap)// 输出:开始渲染谷歌地图
renderMap(baiduMapAdapter)// 输出:开始渲染百度地图

你可能感兴趣的:(坚持周总结)