设计模式——装饰器模式(作用、意义、实现before、after、es7中的修饰符)

作用及意义

其实使用装饰器模式就是我压根不想去关心它现有的业务逻辑是什么。我只是想对它已有的功能做个拓展,只关心拓展出来的那部分新功能如何实现。

实际工作中的运用(简单粗暴)

老板交给小明一个远古项目,告诉小明相关开发已经跑路离职,没有任何交接文档。你来给我修改下这个Low代码,添加一段你写的Low代码。

小明粗暴的写下了如下代码

function lowCode(){
    console.log('大量很Low的代码')
}

function myCode(){
    console.log('自己写Low代码')
}

// 将新功能与老功能组合
function moreCode(){
    lowCode()
    myCode()
}
moreCode()

小明看了自己写的代码,我不要当lowbe,毕竟我是会Java的前端开发工程师。于是有了下面的这段代码。

//原始的low代码
var LowCode = function () {

};
LowCode.prototype.log = function () {
    console.log('大量的Low的代码');
};

//装饰类
var LowDecorator = function (lowCode) {
    this.lowCode = lowCode;
}
//装饰类中的方法
LowDecorator.prototype.log = function () {
    this.lowCode.log();
    console.log('自己写Low代码!');
};

var lowCode = new LowCode();
lowCode = new LowDecorator(lowCode);
lowCode.log();

es6如何实现呢

class LowCode {
    log() {
        console.log('大量的Low的代码');
    };
}

class LowDecorator {
    constructor(lowCode){
        this.lowCode=lowCode
    }
    log() {
        this.lowCode.log();
        console.log('自己写Low代码!');
    };
}
var lowCode = new LowCode();
lowCode = new LowDecorator(lowCode);
lowCode.log();

仔细的想一想这样真的合理么,我如果想修饰一个类。需要重新构造一个类,这完全就是Java的变成思想啊。小明不是Java工程师么前端工程师么?

class LowCode {
    log() {
        console.log('大量的Low的代码');
    };
}
//定义修饰器方法传入一个类 返回一个修饰过类
function lowDecorator(lowCode) {
    var log = lowCode.log;
    lowCode.log = function () {
        log();
        console.log('自己写Low代码!');
    };
    return lowCode
}
var lowCode = lowDecorator(new LowCode())
lowCode.log();
实现before、after修饰方法
// 这一步份设计代理的概念,如果不懂得道友可以等后续的系列文章
Function.prototype.before=function (beforefn) {
    var _this= this;                               //保存旧函数的引用
    return function () {                           //返回包含旧函数和新函数的“代理”函数
        beforefn.apply(this,arguments);            //执行新函数,且保证this不被劫持,新函数接受的参数
                                                   // 也会被原封不动的传入旧函数,新函数在旧函数之前执行
        return _this.apply(this,arguments);
    };
};
function lowCode(){
    console.log('大量很Low的代码')
}
const low = lowCode.before(function(){
    console.log('写在前面的low代码')
})
low()

同理实现 after 方法

Function.prototype.after=function (afterfn) {
    var _this=this;
    return function () {
        var ret=_this.apply(this,arguments);
        afterfn.apply(this,arguments);
        return ret;
    };
};
function lowCode(){
    console.log('大量很Low的代码')
}
const low = lowCode.after(function(){
    console.log('写在后面的low代码')
})
low()

关于es7中的修饰符

在讲es7修饰符之前呢,需要先解决es7编译问题。当然是babel大法啦!

yarn //初始化
yarn add  babel babel-preset-env babel-plugin-transform-decorators-legacy --dev //安装依赖

目录结构如下

├── .babelrc
├── dist
│   └── index.js
├── package.json
├── src
│   └── index.js
└── yarn.lock

.babelrc配置

{
    "presets": ["env"],
    "plugins": ["transform-decorators-legacy"]
}

执行命令

yarn babel  src --watch --out-dir dist

修饰类

// 装饰器函数,它的第一个参数是目标类 
function classDecorator(target) {
    target.hasDecorator = true
  	return target
}
// 将装饰器“安装”到Button类上
@classDecorator
class LowCode {

}
// 验证装饰器是否生效
console.log('LowCode是否被装饰了:', LowCode.hasDecorator) //true

修饰方法

// 第一个参数目标对函数  第二个是函数名字 第三个参数 属性描述对象
// descriptor 可以理解为 Object.defineProperty
function funcDecorator(target, name, descriptor) {
    let originalMethod = descriptor.value
    descriptor.value = function () {
        console.log('我是Func的装饰器逻辑')
        return originalMethod.apply(this, arguments)
    }
    return descriptor
}

class Button {
    @funcDecorator
    onClick() {
        console.log('我是Func的原有逻辑')
    }
}
(new Button).onClick()
// 我是Func的装饰器逻辑
// 我是Func的原有逻辑

此处就不做过多的介绍了,有兴趣的道友建议去阅读阮一峰的ES6。我就不误人子弟做过多描述了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵忠洋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值