什么是设计模式?为什么要使用设计模式?
设计模式是软件开发过程中的通用解决方案(23种),不是特种语言的,是一种编程思想。
一般来说,在代码设计中,我们应当遵循「多用组合,少用继承」的原则。通过装饰器模式动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活,让代码变得更加优雅。
装饰器
允许向一个对象添加一个新的功能,但不改变原有对象,装饰器使用 @
作为标识符,被放置在被装饰代码前面。
通俗的讲就是人在不同的季节穿不同的衣服,人就是那个对象,衣服就是装饰器。
装饰器原始实现
/* 画个圆 */
class Circle {
//行为画圆
draw () {
console.log("画个圆")
}
}
/**
* 给圆描个边框(不改变原先的类)
* */
class DarwBord {
constructor (circle) {
this.circle = circle
}
//这其实就是一个装饰器,即实现了画圆又实现描边
draw () {
this.circle.draw();
this.drawBord()
}
//行为描边
drawBord () {
console.log("画边框");
}
}
const circle = new Circle()
const drawBoard = new DarwBord(circle)
drawBoard.draw()
装饰器----注解形式(注意:ES6不识别注释装饰 @run ,装饰器是最新的 ECMA 中的一个提案,是一种与类(class)相关的语法,用来注释或修改类和类方法
)
//装饰器----注解形式
class Boy {
@run //注解装饰
speak () {
console.log('我能唱歌')
}
}
/**
* 装饰器
* @param target Boy对象
* @param key 被装饰的方法名
* @param descriptor 描述对象
*/
function run (target, key, descriptor) {
console.log(target, key, descriptor)
console.log("我能跑步")
}
const boy = new Boy()
boy.speak()
装饰器----给方法添加日志
class Math {
@log //给方法添加日志输出功能
add (a, b) {
return a + b
}
}
function log (target, name, descriptor) {
const oldValues = descriptor.value; //oldValues其实指的是Math里的add方法
//重构
descriptor.value = function () {
//arguments js内置对象 包括该函数的所有实参
console.log(`调用${name} 参数:`, arguments)
//target 作用域
return oldValues.apply(target, arguments)
}
console.log(descriptor)
return descriptor
}
const math = new Math();
math.add(1, 3)
装饰器----带参数的
class Math {
@log(100) //给方法添加日志输出功能
add (a, b) {
return a + b
}
}
//日志装饰器
function log (num) { //闭包
return function (target, name, descriptor) {
const _num = num || 0;//
const oldValues = descriptor.value; //oldValues其实指的是Math里的add方法
//重构
descriptor.value = function (...arg) {
arg[0] += _num
arg[1] += _num
//arguments js内置对象 包括该函数的所有实参
console.log(`调用${name} 参数:`, arg)
//target 作用域
return oldValues.apply(target, arg)
}
console.log(descriptor)
return descriptor
}
}
const math = new Math();
console.log(math.add(1, 3))
代码仓库地址gitee.com/wangsf1/dec…