装饰器模式
Posted 沿着路走到底
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器模式相关的知识,希望对你有一定的参考价值。
概念
为对象添加新功能
不改变其原有的结构和功能
示例
手机上套一个壳可以保护手机,壳上粘一个指环,可以挂在手指上不容易滑落,这就是一种装饰。手机还是那个手机,手机的功能一点都没变,只是在手机的外面装饰了一些其他附加的功能。日常生活中,这样的例子非常多。
UML类图
代码演示
class Circle
draw()
console.log('画一个原型')
class Decorator
constructor(circle)
this.circle = circle
draw()
this.circle.draw()
this.setRedBoder(circle)
setRedBoder(circle)
console.log('设置红色边框')
// 测试代码
let circle = new Circle()
circle.draw()
let dec = new Decorator(circle) // 装饰
dec.draw()
ES7 装饰器
安装`npm i babel-plugin-transform-decorators-legacy --save-dev`,然后修改`.babrlrc`
"presets": ["es2015", "latest"],
"plugins": ["transform-decorators-legacy"]
装饰器的原理
@decorator
class A
// 等同于
class A
A = decorator(A) || A;
装饰类
```js
// 一个简单的 demo
@testDec
class Demo
// ...
function testDec(target)
target.isDec = true;
alert(Demo.isDec) // true
```
//可以加参数
```js
// 可以加参数
function testDec(isDec)
return function(target)
target.isDec = isDec;
@testDec(true)
class Demo
// ...
alert(Demo.isDec) // true
```
// mixin 示例
```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() // 'foo'
```
装饰方法
// 先看一个 readonly 的 demo
```js
function readonly(target, name, descriptor)
// descriptor 属性描述对象(Object.defineProperty 中会用到),原来的值如下
//
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// ;
descriptor.writable = false;
return descriptor;
class Person
constructor()
this.first = 'A'
this.last = 'B'
// 装饰方法
@readonly
name() return `$this.first $this.last`
var p = new Person()
console.log(p.name())
// p.name = function () // 这里会报错,因为 name 是只读属性
```
//再看一个例子,加一个装饰器自动打印日志
```js
function log(target, name, descriptor)
var 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;
const math = new Math();
const result = math.add(2, 4); // 执行 add 时,会自动打印日志,因为有 @log 装饰器
console.log('result', result);
```
core-decorators
[core-decorators.js](https://github.com/jayphelps/core-decorators) 是一个第三方模块,提供了几个常见的修饰器,通过它可以更好地理解修饰器。
用之前肯定得先安装`npm i core-decorators --save`,然后先用它来实现上述的 readonly
```js
// 首先安装 npm i core-decorators --save
// 开始编码:
import readonly from 'core-decorators'
class Person
@readonly
name()
return 'zhang'
let p = new Person()
alert(p.name())
// p.name = function () /*...*/ // 此处会报错
```
在看一个常用的例子,对已经弃用的协议,给出警告。
```js
import deprecate from 'core-decorators';
class Person
@deprecate
facepalm()
@deprecate('We stopped facepalming')
facepalmHard()
@deprecate('We stopped facepalming', url: 'http://knowyourmeme.com/memes/facepalm' )
facepalmHarder()
let person = new Person();
person.facepalm();
// DEPRECATION Person#facepalm: This function will be removed in future versions.
person.facepalmHard();
// DEPRECATION Person#facepalmHard: We stopped facepalming
person.facepalmHarder();
// DEPRECATION Person#facepalmHarder: We stopped facepalming
//
// See http://knowyourmeme.com/memes/facepalm for more details.
```
1
以上是关于装饰器模式的主要内容,如果未能解决你的问题,请参考以下文章