1. 程式人生 > >golang設計模式(9)裝飾模式

golang設計模式(9)裝飾模式

裝飾模式意圖
動態的給一個物件增加一些額外的職責,就增加功能來說,裝飾模式相比生產子類更為靈活

裝飾模式適用性
以下情況適合使用裝飾模式:
.在不影響其他物件的情況下,動態、透明的方式給單個物件新增職責。
.處理那些可以撤銷的職責。
.當不成採用生成子類的方法進行擴充時。一種情況是,可能會有大量獨立的擴充套件,為支援每一種組合將產生大量的子類。使得子類數目呈現爆炸性增長。另外一種情況可能是型別定義被隱蔽,或類定義不能用於生產子類。

結構
裝飾模式uml

裝飾模式效果
使用裝飾模式有以下優點:
1)使用裝飾模式比靜態繼承更加靈活,和物件的靜態繼承(golang中不存在多重繼承)相比,裝飾模式提供更加靈活的向物件增加職責的方式。可以用新增和分離的方法,用裝飾在執行時刻增加和刪除職責。相比之下,繼承機制要求為每個類新增的職責建立一個新的子類,並且會增加系統的複雜度。此外,為一個特定的Component類提供多個不同的Decorator類,可以使得一些職責進行混合和匹配。
2)避免在層次結構高層的類有太多複雜的特徵

。裝飾模式提供一種“即用即付”的方式來新增職責。並不試圖在一個複雜的可定製的類中支援所有可預見的特徵,相反,可以定義一個簡單的類,並且應用Decorator類給他逐漸地新增功能。可以用簡單的部件組合出複雜的功能。這樣,應用程式不必為不需要的特徵付出代價。同時也不依賴於Decorator所擴充套件的型別而獨立定義新的型別的Decorator。拓展一個複雜的型別時,很可能會暴露與新增的職責無關的細節。

同時裝飾模式也會有一些缺點:
有很多小物件。採用裝飾模式進行系統設計時,往往會產生看上去很類似的小物件,這些物件僅僅在相互連線方式有所不同。這對於對系統很熟悉的人來說,很容易組裝,對需求進行定製。而對開始接觸系統的人來說,卻很難學習。同時在排查錯誤的時候,需要排查大量的小類,導致排錯也比較困難。

總體上來說,裝飾模式對熟悉系統的開發來說特別方便,但是會增加學習難度和降低可維護性。

實現

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 }

執行結果:
發展中公司中:
公司有老闆,有前臺,有人事…
還有開發、測試、財務人員
大型公司中:
發展中公司中:
公司有老闆,有前臺,有人事…
還有開發、測試、財務人員
除此之外,個職能人員應有盡有