裝飾者模式
動態地將責任附加到物件上。想要擴充套件功能,裝飾者提供有別於繼承的另一種選擇。
裝飾者模式 符合開放-關閉原則。繼承 雖然屬於擴充套件的形式之一,但是在設計中,推崇多用組合少用繼承的說法。但是好像 GO 裡面沒有繼承的說法,只有組合。所以用 GO 實現裝飾者模式還是很方便的。裝飾者的主要目的就是對基礎物件不斷的擴充套件功能,雖然在一定程度上保持了擴充套件性,但是如果過度使用會出現眾多小物件,會使程式變得很複雜。
// 飲料介面
type Beverage interface {
getDescription() string
cost() int
}
// 實現咖啡的過程
type Coffee struct {
description string
}
func(this Coffee) getDescription() string {
return this.description
}
func(this Coffee) cost() int {
return 1
}
// Mocha 實現
type Mocha struct {
beverage Beverage
description string
}
func(this Mocha) getDescription() string {
return fmt.Sprintf("%s, %s", this.beverage.getDescription(), this.description)
}
func(this Mocha) cost() int {
return this.beverage.cost() + 1
}
// Whip 實現
type Whip struct {
beverage Beverage
description string
}
func(this Whip) getDescription() string {
return fmt.Sprintf("%s, %s", this.beverage.getDescription(), this.description)
}
func(this Whip) cost() int {
return this.beverage.cost() + 1
}
func main() {
var beverage Beverage
// 買了一杯咖啡
beverage = Coffee{description:"houseBlend"}
// 給咖啡加上 Mocha
beverage = Mocha{beverage:beverage, description:"Mocha"}
// 給咖啡加上 Whip
beverage = Whip{beverage:beverage, description:"whip"}
// 最後計算 Coffee 的價格
fmt.Println(beverage.getDescription(), ", cost is ", beverage.cost())
}
裝飾模式是原始物件的擴充套件,不斷的增加功能。