您现在的位置是:首页 >学无止境 >设计模式之装饰器模式网站首页学无止境
设计模式之装饰器模式
简介设计模式之装饰器模式
装饰器模式:为对象添加新功能,不改变其原有的结构和功能
装饰器模式是原有的功能还能用,但是需要新增一些东西来完善这个功能。比如产品经理让你添加新功能,但又要保证原来的代码不变,你要在原来的方法执行的时候同时出现新功能。比如手机壳,手机本身的功能不受影响,手机壳就是手机的装饰器模式。
比如有个方法,它的功能是:
let handle = () => {
alert(1)
};
新需求是,你要在执行handle函数的时候,顺便再弹出一个2。
这里正常改的话,可能就写成这样:
//修改代码
let handle = () => {
alert(1)
alert(2)
};
但,我们说这样写其实就违反了开闭原则,而且,如果这里的alert(1)并不是一句简单的执行语句,而是一堆复杂的逻辑代码,而alert(2)也并不是简单的alert(2),这个时候,怎么办呢?
我们可以这么写:
//扩展函数
const _handle = handle;
handle = () => {
_handle();
alert(2);
}
我们可以新建一个变量_handle先将原函数保存一下原函数的引用,然后扩展一下handle,执行刚保存的原函数_handle,然后将自己的功能扩展在原函数的下面。
回顾装饰器模式的定义:“在不改变原对象的基础上,对原对象进行包装扩展”,我们发现这里就是一个装饰器模式的应用。
类实现装饰器
class Circle {
draw() {
console.log('画一个圆形');
}
}
class Decorator {
constructor(circle) {
this.circle = circle;
}
draw() {
this.circle.draw();
this.setRedBorder(circle);
}
setRedBorder(circle) {
console.log('设置红色边框')
}
}
// 测试
let circle = new Circle();
let client = new Decorator(circle);
client.draw(); // 17.画一个圆形 29.设置红色边框
使用场景
ES7装饰器
1、安装 npm i babel-plugin-transform-decorators-legacy
在.babelrc文件配置代码:
{
"presets": ["es2015", "latest"],
"plugins": ["transform-decorators-legacy"]
}
2、代码
// 一个简单的demo
@testDec
class Demo {
// ...
}
function testDec(target) {
target.isDec = true
}
alert(Demo.isDec) // true
打印出来了true,说明@testDec这个装饰器已经成功了,函数是个装饰器,用@testDec给Demo装饰了一遍。这个target其实就是class Demo,然后给她加一个isDec
原理
// 装饰器原理
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
传参的形式
@testDec(false)
class Demo {
}
function testDec(isDec) {
return function (target) {
target.isDec = isDec
}
}
alert(Demo.isDec);
设计原则验证
将现有对戏那个和装饰器进行分离,两者独立存在
符合开放封闭原则
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。