5JavaScript设计模式--装饰器模式/代理模式/外观模式

版权声明:本文为作者的原创文章,未经允许不得转载。 https://blog.csdn.net/lin5165352/article/details/81878836
  • 装饰器模式

演示代码

class Circle{
    draw(){
        console.log('绘制一个圆形')
    }
}
class Decorator{
    constructor(circle){
        this.circle = circle
    }
    draw(){
        this.circle.draw()
        this.setRedBouder(circle)
    }
    setRedBouder(circle){
        console.log('设置红色边框')
    }
}

let circle = new Circle()
circle.draw()
let dec = new Decorator(circle)
dec.draw()

在ES7中添加了装饰类。但是目前我们用的ES6还不支持。我们可以通过babel插件来演示。

安装插件: npm install babel-plugin-transform-decorators-legacy --save-dev

配置插件。


//装饰器模式
class Circle{
    draw(){
        console.log('绘制一个圆形')
    }
}
class Decorator{
    constructor(circle){
        this.circle = circle
    }
    draw(){
        this.circle.draw()
        this.setRedBouder(circle)
    }
    setRedBouder(circle){
        console.log('设置红色边框')
    }
}

let circle = new Circle()
circle.draw()
let dec = new Decorator(circle)
dec.draw()

//演示1
@testDec
class Demo{

}
function testDec(target){
    target.isDec = true
}
console.log(Demo.isDec)

//演示二  把属性变成只读
function readonly(target, name, descriptor){
    descriptor.writable = false
    return descriptor
}

class Person {
    constructor(){
        this.first = '张'
        this.last = '三'
    }
    @readonly
    name(){
        return `${this.first} ${this.last}`
    }
}
let p = new Person()
console.log(p.name())
// p.name = function(){
//     return `AABB`
// }
//console.log(p.name()) //修改name会报错,提示name属性只读

//演示三 装饰方法 在前面先打印一下日志 再执行加法
function log(target,name,descriptor){
    let oldValue = descriptor.value
    descriptor.value = function(){
        console.log(`calling ${name} with `,arguments)
        return oldValue.apply(this.arguments)
    }
    return descriptor
}
class Math{
    @log
    add(a,b){
        return a+b 
    }
}
let math = new Math()
const result = math.add(2,3)
console.log('result',result)

core-decorators是第三方开源lib,提供常用的装饰器。可以直接拿来使用和借鉴,不要自己再去摸索。
参考文档:github.com./jayphelps/core-decorators 

npm install core-decorators --save

          

 参考文档中给出了很多方法,可以自己研究。下面演示两种方法。一个是装饰成只读模式。一个是是装饰成废弃模式。

import { readonly } from 'core-decorators'
import { deprecate } from 'core-decorators'
//引用类库 就不需要自己再定义了
class Person {
    @readonly
    name() {
        return '张三'
    }
}
let p = new Person
console.log(p.name())
//p.name = function(){} //会报错 只读模式

class People {
    // 打印默认提示内容:DEPRECATION People#name: This function will be removed in future versions.
    // @deprecate() 
    //  也打印自定义的内容:DEPRECATION People#name: 该方法即将弃用
    //  See https://github.com/jayphelps/core-decorators for more details.
    @deprecate('该方法即将弃用',{url:'https://github.com/jayphelps/core-decorators'})
    name() {
        return '李四'
    }
}
let peo = new People();
peo.name()

  • 代理模式
//代理模式 演示通过代理模式访问外网图片
class ReadImg{
    constructor(fileName){
        this.fileName = fileName
        this.loadFromDisk()
    }
    display(){
        console.log('display....'+this.fileName)
    }
    loadFromDisk(){
        console.log('loading...'+this.fileName)
    }
}

class ProxyImg{
    constructor(fileName){
        this.realImg = new ReadImg(fileName)
    }
    display(){
        this.realImg.display()
    }
}

let proxy = new ProxyImg('cat.jpg')
proxy.display()

//ES6中 proxy
//明星
let star = {
    name: '李寻欢',
    age:28,
    phone:'15296002163'
}
//经纪人
let agent = new Proxy(star,{
    get:function(target,key){
        if(key === 'phone'){
            return '152-1233-9087' //返回经纪人电话
        }
        if(key === 'price'){
            return 120000
        }
        return target[key]
    },
    set:function(target,key,val){
        if(key === 'customPrice'){
            if(val < 100000){
                throw new Error('价格太低,免谈')
            }else{
                target[key] = val
                return true
            }
        }
    }
})

console.log(agent.name)
console.log(agent.age)
console.log(agent.phone)
console.log(agent.price)
console.log(agent.high)

agent.customPrice = 150000
console.log('agent.customPrice',agent.customPrice)
agent.customPrice = 90000
console.log('agent.customPrice',agent.customPrice)

ES6 中引入了Proxy语法。


  • 外观模式

00

猜你喜欢

转载自blog.csdn.net/lin5165352/article/details/81878836
今日推荐