建造者模式是一種創建型模式,主要用來創建比較復雜的對象。
建造者模式的使用場景:
- 建造者模式通常適用於有多個構造器參數或者需要較多構建步驟的場景。使用建造者模式可以精簡構造器參數的數量,讓構建過程更有條理。
- 可以為同一個產品提供兩個不同的實現。比如,在下面的代碼中,為
house
類型創建了兩個不同的實現:通過iglooBuilder構建的igloo(冰屋),以及通過cabinBuilder構建的cabin(木屋) - 可以應用於構建過程不允許被中斷的場景。仍然參考剛才的代碼,
house
類型的對象要么徹底完成,要么壓根沒有創建,不會存在中間狀態,這是因為structdirector
封裝了相應的過程,中間狀態僅存在於ConcreteBuilder中。
下面是UML類圖:
代碼大致如下。
house.go:
package main type house struct { windowType string doorType string floor int }
iBuilder.go:
package main type iBuilder interface { setWindowType() setDoorType() setNumFloor() getHouse() house } func getBuilder(builderType string) iBuilder { if builderType == "cabin" { return &cabinBuilder{} } if builderType == "igloo" { return &iglooBuilder{} } return nil }
iglooBuilder.go
package main type iglooBuilder struct { house } func newIglooBuilder() *iglooBuilder { return &iglooBuilder{} } func (b *iglooBuilder) setWindowType() { b.windowType = "Ice Window" } func (b *iglooBuilder) setDoorType() { b.doorType = "Ice Door" } func (b *iglooBuilder) setNumFloor() { b.floor = 1 } func (b *iglooBuilder) getHouse() house { return b.house }
cabinBuilder.go
package main type cabinBuilder struct { house } func newCabinBuilder() *cabinBuilder { return &cabinBuilder{} } func (b *cabinBuilder) setWindowType() { b.windowType = "Wooden Window" } func (b *cabinBuilder) setDoorType() { b.doorType = "Wooden Door" } func (b *cabinBuilder) setNumFloor() { b.floor = 2 } func (b *cabinBuilder) getHouse() house { return b.house }
director.go
package main type director struct { builder iBuilder } func newDirector(b iBuilder) *director { return &director{ builder: b, } } func (d *director) setBuilder(b iBuilder) { d.builder = b } func (d *director) buildHouse() house { d.builder.setDoorType() d.builder.setWindowType() d.builder.setNumFloor() return d.builder.getHouse() }
最后是main方法:
package main import ( "fmt" ) func main() { cabinBuilder := getBuilder("cabin") iglooBuilder := getBuilder("igloo") director := newDirector(cabinBuilder) cabinHouse := director.buildHouse() fmt.Printf("Cabin House Door Type: %s\n", cabinHouse.doorType) fmt.Printf("Cabin House Window Type: %s\n", cabinHouse.windowType) fmt.Printf("Cabin House Num Floor: %d\n", cabinHouse.floor) director.setBuilder(iglooBuilder) iglooHouse := director.buildHouse() fmt.Printf("\nIgloo House Door Type: %s\n", iglooHouse.doorType) fmt.Printf("Igloo House Window Type: %s\n", iglooHouse.windowType) fmt.Printf("Igloo House Num Floor: %d\n", iglooHouse.floor) }
代碼已上傳到GitHub:zhyea / go-patterns / builder-pattern
End!