Skip to main content

装饰器模式 Decorator Pattern

介绍

  • 为对象添加新功能
  • 不改变其原有的结构和功能

示例

类图:

classDiagram

Client --> Decorator
Decorator --> Circle

class Client {
+ circle: Circle
+ dec: Decorator
+main () void
}

class Decorator {
cricle: Circle
+draw() void
+setBorderStyle(circle)
}

class Circle {
+draw() void
}
class Circle {
draw(){
console.log('draw circle')
}
}

class Decorator{
constructor(circle) {
this.circle = new Circle()
}

draw() {
this.circle.draw()
this.setborderStyle()
}

setborderStyle() {
console.log('set style..')
}
}

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

应用场景

ES7 装饰器

定义一个类 Demo,定义装饰器 testDec, @testDec写在class Demo前,testDec 可以获取到参数 target,即当前的 demo 类。然后就可以在 testDec 中对 demo 的属性做处理。

例子 1, 带参的装饰器

// 需安装 @babel/plugin-proposal-decorators
@testDec(false)
class Demo{

}

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

装饰器对类的行为的改变是在代码编译时发生的,不是在运行时

@decorators
class A{}
// 相当于 👇🏻
class A{}
A = decorators(A) || A

例子 2

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

const Foo1 = {
foo1() {
console.log('foo1')
}
}

const Foo2 = {
foo2() {
console.log('foo2')
}
}

@mixins([Foo1, Foo2])
class MyClass{}

const obj = new MyClass()
obj.foo1()
obj.foo2()

例子 3

function readOnly(target, prop, description) {
description.writable = false
return description
}

class Person {
constructor() {
this.name = 'olu'
this.age = 18
}

// 装饰方法
@readOnly
getInfo() {
return `name: ${this.name}, age: ${this.age}`
}
}

const p = new Person
p.getInfo = function() {
console.log('olucool')
}
console.log(p.getInfo()) // 还是原先的,未被修改

例子 4

function log (target, name, description) {
const oldValue = description.value
description.value = function () {
console.log(`calling ${name} with ${arguments}`)
return oldValue.apply(this, arguments)
}
return description
}

class Math{
@log
add(a, b) {
return a + b
}
}

const m = new Math();
const sum = m.add(1,4) // 5

三方库 core-decorators

设计原则验证

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