// 装饰模式的经典实现,AOP,在不改变原有函数行为的情况下插入方法 // T: 入参类型,U: 返回结果类型 export class AOP { funcs: ((...arg: T[]) => U | any)[]; result: U; constructor( fn?: (...arg: T[]) => U, res?: U, initFuncs: ((...arg: T[]) => U | any)[] = [], ) { this.funcs = initFuncs; this.result = res; if (fn) { this.funcs.push(fn); } } // after: after(afterFn?: (...param: T[]) => void) { this.funcs.push(afterFn); return new AOP(null, this.result, this.funcs); } // before: before(before?: (...param: T[]) => void) { this.funcs.unshift(before); return new AOP(null, this.result, this.funcs); } getFunction() { const res = this.result; const funcs = this.funcs; return function(...params: T[]) { funcs.forEach(fn => { fn(...params); }); return res; }; } }