Hi!这里是 JustHappy,咱前端写多了组件、搞多了逻辑,是不是总会遇到某些功能“忍不住想加一嘴”?又不想动原来的代码?那你就该认识一下——装饰器模式(Decorator Pattern) 啦!
装饰器模式是啥?🎁
来!我们还得看看百科怎么说!(以下引用自维基百科)
在设计模式中,装饰器模式(Decorator Pattern)允许向一个现有对象添加新的功能,同时又不改变其结构。这个模式创建了一个装饰类,用来包裹原有的类,并在保持原有类方法签名完整性的前提下,提供额外的行为。
一句话总结:你不动原来的代码,就能加功能!是不是很香?
来个生活化比喻 🎩
你买了杯咖啡(原始对象),但你突然想加点奶加点糖甚至来点抹茶?你不会去工厂改配方,而是……一层一层往上加!
☕ 咖啡 + 奶 → 奶咖
☕ 咖啡 + 糖 → 甜咖
☕ 咖啡 + 奶 + 糖 + 抹茶 → 精致贵妇快乐水
这就是装饰器模式的精髓!
🌈 试想一个场景!
比如你写了一个 log() 函数,控制台输出日志:
function log(message) {
console.log(message)
}
某一天你领导说:“能不能加个时间戳?”
你加了:
function log(message) {
console.log(`[${new Date().toISOString()}] ${message}`)
}
又过了两天:“能不能加个颜色?”
你又加了:
function log(message) {
console.log(`%c[${new Date().toISOString()}] ${message}`, 'color: green')
}
再后来……你疯了……
🧠 冷静下来,来点“装饰器模式”!
我们不改原来的 log() 函数,而是“装饰”它!
// 基础 log 函数,支持样式参数
function log(message, style = '') {
console.log(`%c${message}`, style)
}
// 装饰器1:加时间戳
function withTimestamp(fn) {
return function(message, style) {
const timestamp = `[${new Date().toISOString()}]`
fn(`${timestamp} ${message}`, style)
}
}
// 装饰器2:大写输出
function withUpperCase(fn) {
return function(message, style) {
fn(message.toUpperCase(), style)
}
}
// 装饰器3:加颜色样式
function withColor(fn, color = 'green') {
return function(message, style = '') {
const combinedStyle = `color: ${color}; ${style}`
fn(message, combinedStyle)
}
}
// 装饰器组合(从里到外,顺序很重要)
let enhancedLog = withColor(
withUpperCase(
withTimestamp(log)
),
'blue'
)
// 使用
enhancedLog('Hello, Decorator!')
👀 输出效果:
🧬 装饰器模式的几个关键词!
| 🔧 特性 | ✅ 说明 |
|---|---|
| 开闭原则 | 对扩展开放,对修改封闭! |
| 灵活组合 | 想怎么装就怎么装,叠叠乐~ |
| 保持原接口 | 不改原有代码,老代码继续跑 |
| 类 or 函数都能用 | JS世界里都能玩得转 |
💡 在前端项目里怎么玩?
- ✅ 日志增强:如上面那样包装
console.log - ✅ 组件增强:高阶组件(HOC)其实就是 React 里的装饰器!
- ✅ 请求包装:封装 fetch,自动加 token、加 loading、加缓存
- ✅ 表单校验:字段装饰,校验逻辑统一注入
📝 最后总结一下!
装饰器模式,就像给已有能力 “加特效”:
- 你不破坏原功能 ✅
- 你可以层层叠加 ✅
- 最终效果华丽又不乱 ✅