Skip to content

单例模式

0、定义

TIP

1、为对象添加新功能

2、不改变起原有的结构和功能

1、设计原则验证

  • 1、将现有对象和装饰器进行分离,两者独立存在
  • 2、符合开放封闭原则

2、示例

示例:手机壳

deign

3、代码

js
class Circle {
    draw() {
        console.log('画一个圆形')
    }
}

class Decorator {
    constructor() {
        this.circle = new Circle()
    }
    draw() {
        this.circle.draw()
        this.setRedBorder(circle)
    }
    setRedBorder(circle) {
        console.log('设置红色边框')
    }
}

// 测试
let circle = new Circle()
circle.draw()

console.log('--------分割线---------')

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

4、经典场景

4.1、ES7装饰器

js
// 安装插件
npm install @babel/plugin-proposal-decorators --save-dev --registry=https://registry.npm.taobao.org

// webpack配置中加入插件
options: {
   presets: ['@babel/preset-env'],
   plugins: [
      ['@babel/plugin-proposal-decorators', {'legacy': true }]
     ]
 }

// 环境测试代码
@testDec
class Demo {
    
}

function testDec(target) {
    target.isDec = true
}

alert(Demo.isDec)

4.2、示例1

js
function testDec(isDec) {
    return function(target) {
        target.isDec = isDec
    }
}

@testDec(false)
class Demo {
    
}

alert(Demo.isDec)

4.3、示例2-参数

js
function mixins(...list) {
    return function(target) {
        Object.assign(target.prototype, ...list)
    }
}

const Foo = {
    foo() {
        alert('foo')
    }
}
@mixins(Foo)
class MyClass {
    
}

let obj = new MyClass()
obj.foo()

4.4、示例3-只读属性

js
function readonly(target, name, descriptor) {
    descriptor.writable = false
    return descriptor
}

class Person {
    constructor() {
        this.first = 'A'
        this.last = 'B'
    }

    @readonly
    name() {
        return `${this.first} ${this.last}`
    }
}

let p = new Person()
console.log(p.name())

// 修改不生效
p.name = function() {
    console.log('100')
}

console.log(p.name())

4.5、示例4-打印log

js
function log(target, name, descriptor) {
    let oldValue = descriptor.value
    descriptor.value = function() {
        console.log(`calling ${name} width `, 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, 4)
console.log('result', result)

4.6、类库:core-decorators

js
npm i core-decorators --save --registry=https://registry.npm.taobao.org
js
// 案例1
import { readonly } from 'core-decorators'

class Person {
    @readonly
    name() {
        return 'zhang san'
    }
}

let p = new Person()
alert(p.name())

// 修改报错: Cannot assign to read only property 'name' of object '#<Person>'
p.name = function () {

}
js
// 案例2
import { deprecate } from 'core-decorators'

class Person {
    @deprecate('即将废用', {url: 'www.baidu.com'})
    name() {
        return 'zhang san'
    }
}

let p = new Person()
alert(p.name())

Released under the MIT License.