golang設計模式之建造者模式

silsuer在掘金發表於2018-11-26

建造者模式

最近一直在寫框架,這個系列也好久沒更新了,抽時間更新一篇~

概述

wiki: 建造者模式(Builder Pattern):將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

直白一點的說,就是將我們在開發過程中遇到的大型物件,拆分成多個小物件,然後將多個小物件組裝成大物件,並且對外部隱藏建造過程.

結構

建造者模式由一下4個部分組成

  • Builder: 抽象建造者

  • ConcreteBuilder: 具體建造者

  • Director: 指揮者

  • Production: 產品(大型產品以及拆分成的小型產品)

類圖 && 時序圖

golang設計模式之建造者模式
golang設計模式之建造者模式

(圖源網路)

從上面兩張圖可以看出建造者模式的使用流程:

  1. 建立大型產品建造者
  2. 建立指揮者
  3. 將建造者傳入指揮者物件中
  4. 由指揮者指揮建造者建立物件,並返回

舉個栗子

說一個網上說爛了的組裝汽車的栗子吧,

比如說我是個老司機,但是除了開車還想造車,但是車的構造實在是太複雜了,那麼我們就可以將車拆分...

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框架完成後我會再來補充這一部分.

上述程式碼均放在 golang-design-patterns 這個倉庫中

打個廣告,推薦一下自己寫的 go web框架 bingo,求star,求PR ~

相關文章