一個菜鳥的設計模式之旅,文章可能會有不對的地方,懇請大佬指出錯誤,
編程旅途是漫長遙遠的,在不同時刻有不同的感悟,本文會一直更新下去,
程式介紹

本程式實作裝飾模式,小明和小王去吃沙縣小吃,各自喜歡不同的搭配,需要考慮每個人飲食喜好不同,隨時可能的變化,
小明想吃不帶湯的面
拿個碗裝了面條加個炸蛋加牛肉片加點醬汁
小王想吃餛飩,還特別愛吃雞腿
拿個碗裝了餛飩加個雞腿加個雞腿加點湯
程式代碼
decorator.go
package main
import "fmt"
type component interface {
operation()
}
type noodle struct{}
type huntun struct{}
func (e noodle) operation() {
fmt.Printf("拿個碗裝了面條")
}
func (e huntun) operation() {
fmt.Printf("拿個碗裝了餛飩")
}
type decorator struct {
component component
}
func (d *decorator) setComponent(c component) {
d.component = c
}
func (d *decorator) operation() {
if d.component != nil {
d.component.operation()
}
}
type egg struct{ decorator }
type beef struct{ decorator }
type sauce struct{ decorator }
type soup struct{ decorator }
type chicken struct{ decorator }
func (e egg) operation() {
e.decorator.operation()
fmt.Printf("加個炸蛋") // 可以是該結構型別獨有的方法
}
func (e beef) operation() {
e.component.operation()
fmt.Printf("加牛肉片")
}
func (e sauce) operation() {
e.component.operation()
fmt.Printf("加點醬汁")
}
func (e soup) operation() {
e.component.operation()
fmt.Printf("加點湯")
}
func (e chicken) operation() {
e.component.operation()
fmt.Printf("加個雞腿")
}
main.go
package main
import "fmt"
func main() {
fmt.Println("小明想吃不帶湯的面")
noodle := noodle{}
egg := egg{decorator{noodle}}
beef := beef{decorator{egg}}
sauce := sauce{decorator{beef}}
sauce.operation()
/* -------------------------------------------------------------------------- */
fmt.Println("\n小王想吃餛飩,還特別愛吃雞腿")
huntun := huntun{}
chicken1 := chicken{}
chicken2 := chicken{}
soup := soup{}
chicken1.setComponent(huntun)
chicken2.setComponent(chicken1)
soup.setComponent(chicken2)
soup.operation()
}
Console
小明想吃不帶湯的面
拿個碗裝了面條加個炸蛋加牛肉片加點醬汁
小王想吃餛飩,還特別愛吃雞腿
拿個碗裝了餛飩加個雞腿加個雞腿加點湯
思考總結
什么是裝飾模式
裝飾器模式(Decorator Pattern)允許向一個現有的物件添加新的功能,同時又不改變其結構,這種型別的設計模式屬于結構型模式,它是作為現有的類的一個包裝,

裝飾模式:動態地給一個物件添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活,
面對變化,如果采用生成子類的方式進行擴充,為支持每一種擴展的組合,會產生大量的子類,事實上,這些子類多半只是為某個物件增加一些職責,此時通過裝飾模式,可以更加靈活、動態、透明的方式給單個物件添加職責,在不需要時也可以撤銷相應職責,這種模式創建了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能,
主要解決:一般的,我們為了擴展一個類經常使用繼承方式實作,由于繼承為類引入靜態特征,并且隨著擴展功能的增多,子類會很膨脹,
何時使用:在不想增加很多子類的情況下擴展類,
如何解決:將具體功能職責劃分,同時繼承裝飾者模式,
關鍵代碼: 1、Component 類充當抽象角色,不應該具體實作, 2、修飾類參考和繼承 Component 類,具體擴展類重寫父類方法,
應用實體: 1、孫悟空有 72 變,當他變成"廟宇"后,他的根本還是一只猴子,但是他又有了廟宇的功能, 2、不論一幅畫有沒有畫框都可以掛在墻上,但是通常都是有畫框的,并且實際上是畫框被掛在墻上,在掛在墻上之前,畫可以被蒙上玻璃,裝到框子里;這時畫、玻璃和畫框形成了一個物體,
優點:裝飾類和被裝飾類可以獨立發展(類的核心職責和裝飾功能相互分開),不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾模式可以動態擴展一個實作類的功能,把類中的裝飾功能從類中搬移去除,這樣簡化原來的類,
缺點:多層裝飾比較復雜,
使用場景: 1、擴展一個類的功能, 2、動態增加功能,動態撤銷,
注意事項:可代替繼承,當系統需要新功能的時候,是向舊的類中添加新的代碼,這些新加的代碼通常裝飾了原有類的核心職責或主要行為,由于在主類或子類中加入了新的欄位、新的方法、新的邏輯,從而增加了主類的復雜度,而加入這些東西僅僅是為了滿足一些只在某種特定情況下才會執行的特殊行為,
靈活變通:如果只有一個ConcreteComponent類沒有抽象的Component類,那么Decorator類可以是ConreteComponent的一個子類,如果只有一個ConcreteDecorator類,那么就沒有必要單獨建立一個Decorator類,可以把Decorator和ConcreateDecorator的責任合并成一個類,
與建造者模式不同點:建造者模式要求建造程序必須是穩定的,而裝飾模式可以是不固定程序,可以組合出無數種方案,
參考資料
- 《Go語言核心編程》李文塔
- 《Go語言高級編程》柴樹彬、曹春輝
- 《大話設計模式》程杰
- 單例模式 | 菜鳥教程
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/506017.html
標籤:其他
上一篇:閉包第一天
下一篇:我的設計模式之旅 ⑥ 代理模式
