裝飾器模式
- 在不影響原有功能的情況下,增加新功能
- 裝飾可以增加多個,給共同目標對象添加額外功能
代碼例子
es5代碼
// 毛坯房,目標對象
function OriginHouse() {}
OriginHouse.prototype.getDesc = function() {
console.log('毛坯房')
}
// 粉牆刷漆-裝飾器
function Painting(house) {
this.house = house
}
Painting.prototype.getDesc = function() {
this.house.getDesc()
console.log('粉牆刷漆')
}
// 搬入傢俱-裝飾器
function Furniture(house) {
this.house = house
}
Furniture.prototype.getDesc = function() {
this.house.getDesc()
console.log('搬入傢俱')
}
var house = new OriginHouse()
house = new Painting(house)
house = new Furniture(house)
house.getDesc()
es6代碼
class OriginHouse {
getDesc() {
console.log('毛坯房')
}
}
class Painting {
constructor(house) {
this.house = house
}
getDesc() {
this.house.getDesc()
console.log('粉牆刷漆')
}
}
class Furniture {
constructor(house) {
this.house = house
}
getDesc() {
this.house.getDesc()
console.log('搬入傢俱')
}
}
let house = new OriginHouse()
house = new Painting(house)
house = new Furniture(house)
house.getDesc() // 毛坯房 -> 粉牆刷漆 -> 搬入傢俱
優缺點
優點:
- 裝飾者與被裝飾者之間松耦合,可維護性高
- 被裝飾者可以使用裝飾者動態增加和撤銷功能,靈活
- 每個裝飾器有特定功能,方便複用
- 可以通過選擇不同裝飾器的組合,創造不同行爲和功能的結合體,符合開閉原則
缺點:
- 使用裝飾者模式會產生很多細粒度的裝飾者對象,裝飾者對象由於接口和功能的多樣化導致系統複雜度增加,功能越複雜,需要的細粒度對象越多
- 由於更大的靈活性,也更容易出錯,特別是多級裝飾的場景,錯誤定位更爲繁瑣
場景
- 如果不希望系統中增加很多子類
- 對現有的一組基本功能的排列組合而產生更多功能時
- 當對象的功能要求可以動態添加,動態撤銷時
其他相關模式
- 裝飾者模式:擴展功能,原有功能還可以直接使用,一般可以給目標對象多次疊加使用多個裝飾者;
- 適配器模式:功能不變,但是轉換了原有接口的訪問格式,一般只給目標對象使用一次