golang設計模式(9)裝飾模式
裝飾模式意圖
動態的給一個物件增加一些額外的職責,就增加功能來說,裝飾模式相比生產子類更為靈活
裝飾模式適用性
以下情況適合使用裝飾模式:
.在不影響其他物件的情況下,動態、透明的方式給單個物件新增職責。
.處理那些可以撤銷的職責。
.當不成採用生成子類的方法進行擴充時。一種情況是,可能會有大量獨立的擴充套件,為支援每一種組合將產生大量的子類。使得子類數目呈現爆炸性增長。另外一種情況可能是型別定義被隱蔽,或類定義不能用於生產子類。
結構
裝飾模式效果
使用裝飾模式有以下優點:
1)使用裝飾模式比靜態繼承更加靈活,和物件的靜態繼承(golang中不存在多重繼承)相比,裝飾模式提供更加靈活的向物件增加職責的方式。可以用新增和分離的方法,用裝飾在執行時刻增加和刪除職責。相比之下,繼承機制要求為每個類新增的職責建立一個新的子類,並且會增加系統的複雜度。此外,為一個特定的Component類提供多個不同的Decorator類,可以使得一些職責進行混合和匹配。
2)避免在層次結構高層的類有太多複雜的特徵
同時裝飾模式也會有一些缺點:
有很多小物件。採用裝飾模式進行系統設計時,往往會產生看上去很類似的小物件,這些物件僅僅在相互連線方式有所不同。這對於對系統很熟悉的人來說,很容易組裝,對需求進行定製。而對開始接觸系統的人來說,卻很難學習。同時在排查錯誤的時候,需要排查大量的小類,導致排錯也比較困難。
總體上來說,裝飾模式對熟悉系統的開發來說特別方便,但是會增加學習難度和降低可維護性。
實現
package main
import (
"fmt"
)
type Company interface {
Showing()
}
type BaseCompany struct {
}
func (pB *BaseCompany) Showing() {
fmt.Println("公司有老闆,有前臺,有人事...")
}
type DevelopingCompany struct {
Company
}
func (pD *DevelopingCompany) AddWorker() {
fmt.Println("還有開發、測試、財務人員" )
}
func (pD *DevelopingCompany) Showing() {
fmt.Println("發展中公司中:")
pD.Company.Showing()
pD.AddWorker()
}
type BigCompany struct {
Company
}
func (pD *BigCompany) AddWorker() {
fmt.Println("除此之外,個職能人員應有盡有")
}
func (pD *BigCompany) Showing() {
fmt.Println("大型公司中:")
pD.Company.Showing()
pD.AddWorker()
}
func main() {
company := &BaseCompany{}
developingCompany := &DevelopingCompany{Company: company}
developingCompany.Showing()
bigCompany := &BigCompany{Company: developingCompany}
bigCompany.Showing()
return
}
執行結果:
發展中公司中:
公司有老闆,有前臺,有人事…
還有開發、測試、財務人員
大型公司中:
發展中公司中:
公司有老闆,有前臺,有人事…
還有開發、測試、財務人員
除此之外,個職能人員應有盡有