golang設計模式之建造者模式
最近一直在寫框架,這個系列也好久沒更新了,抽時間更新一篇~
概述
wiki: 建造者模式(Builder Pattern) :將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
直白一點的說,就是將我們在開發過程中遇到的大型物件,拆分成多個小物件,然後將多個小物件組裝成大物件,並且對外部隱藏建造過程.
結構
建造者模式由一下4個部分組成
-
Builder
: 抽象建造者 -
ConcreteBuilder
: 具體建造者 -
Director
: 指揮者 -
Production
: 產品(大型產品以及拆分成的小型產品)
類圖 && 時序圖


( 圖源網路 )
從上面兩張圖可以看出建造者模式的使用流程:
- 建立大型產品建造者
- 建立指揮者
- 將建造者傳入指揮者物件中
- 由指揮者指揮建造者建立物件,並返回
舉個栗子
說一個網上說爛了的組裝汽車的栗子吧,
比如說我是個老司機,但是除了開車還想造車,但是車的構造實在是太複雜了,那麼我們就可以將車拆分...
4個輪子、1個底盤、1個駕駛位...
好了,為了簡便,就造這三個吧,先造個爬犁出來...
所以我需要一個大型專案構造者 CarBuilder
:
type CarBuilder struct { Car *Car } func (cb *CarBuilder) GetResult() interface{} { return cb.Car } func (cb *CarBuilder) NewProduct() { cb.Car = new(Car) } func (cb *CarBuilder) BuildWheels() { cb.Car.Wheels = "build wheels" } func (cb *CarBuilder) BuildChassis() { cb.Car.Chassis = "build chassis" } func (cb *CarBuilder) BuildSeat() { cb.Car.Seat = "build seat" } 複製程式碼
這個建造者實現了 Builder
介面:
type Builder interface { NewProduct()// 建立一個空產品 BuildWheels()// 建造輪子 BuildChassis()// 建造底盤 BuildSeat()// 建造駕駛位 GetResult() interface{}// 獲取建造好的產品 } 複製程式碼
下面要把具體建造者傳入指揮者:
type Director struct { builder Builder } func (d *Director) SetBuilder(builder Builder) { d.builder = builder } 複製程式碼
現在指揮者和建造者都已經準備好了,可以進行建造了,呼叫指揮者的 Generate()
方法:
func (d *Director) Generate() *Car { d.builder.NewProduct() d.builder.BuildChassis() d.builder.BuildSeat() d.builder.BuildWheels() return d.builder.GetResult().(*Car) } 複製程式碼
這樣,就得到了我們需要的 Car
物件:
func main() { // 建立一個指揮者 director := new(Director) // 建立建造者 builder := new(CarBuilder) director.SetBuilder(builder) car := director.Generate() car.Show() } 複製程式碼
總結
上面的程式碼,是將一個本來就不是很複雜的物件,強行拆分,只是將其中的欄位設為最簡單的 string
型別,實際上,這些欄位應該是更小的物件結構體,然後還可以繼續把這些小結構體繼續拆分,拆分為最小單元,這樣才是結構最清晰的思路.
本來想舉一個應用在實際專案中的栗子的,但是框架還沒有寫完,這樣,先佔個坑,等 bingo
框架完成後我會再來補充這一部分.
上述程式碼均放在 ofollow,noindex">golang-design-patterns 這個倉庫中
打個廣告,推薦一下自己寫的 go web框架 bingo ,求star,求PR ~