建造者模式的实现代码
建造者模式(Builder Pattern),又称生成器模式,是较为复杂的创建者模式,它将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端无需知道复杂对象的内部组成部分与装配方式,只需要知道所需的建造者类型即可。
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
package main
import (
"fmt"
)
// house.go
// 房子(产品)
type House struct {
windowType string
doorType string
swimPool string
floor int
}
// iBuilder.go
// 建造者接口(泛指工人)
type IBuilder interface {
setWindowType()
setDoorType()
setNumFloor()
setSwimPool()
getHouse() House
}
func getBuilder(builderType string) IBuilder {
if builderType == "normal" {
return newNormalBuilder()
}
if builderType == "cottages" {
return newCottagesBuilder()
}
return nil
}
// normalBuilder.go
// 普通房子具体建造者(普通工人)
type NormalBuilder struct {
windowType string
doorType string
swimPool string
floor int
}
func newNormalBuilder() *NormalBuilder {
return &NormalBuilder{}
}
func (b *NormalBuilder) setWindowType() {
b.windowType = "Wooden Window"
}
func (b *NormalBuilder) setDoorType() {
b.doorType = "Wooden Door"
}
func (b *NormalBuilder) setNumFloor() {
b.floor = 3
}
func (b *NormalBuilder) setSwimPool() {
b.swimPool = "None"
}
func (b *NormalBuilder) getHouse() House {
return House{
doorType: b.doorType,
windowType: b.windowType,
swimPool: b.swimPool,
floor: b.floor,
}
}
// cottagesBuilder.go
// 别墅具体建设者(别墅工人)
type cottagesBuilder struct {
windowType string
doorType string
swimPool string
floor int
}
func newCottagesBuilder() *cottagesBuilder {
return &cottagesBuilder{}
}
func (b *cottagesBuilder) setWindowType() {
b.windowType = "Glass Window"
}
func (b *cottagesBuilder) setDoorType() {
b.doorType = "Steel Security Door"
}
func (b *cottagesBuilder) setNumFloor() {
b.floor = 1
}
func (b *cottagesBuilder) setSwimPool() {
b.swimPool = "Swimming Pool"
}
func (b *cottagesBuilder) getHouse() House {
return House{
doorType: b.doorType,
windowType: b.windowType,
swimPool: b.swimPool,
floor: b.floor,
}
}
// director.go
// 主管(工头)
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()
d.builder.setSwimPool()
return d.builder.getHouse()
}
// main.go
// 具体工作
func main() {
normalBuilder := getBuilder("normal")
cottagesBuilder := getBuilder("cottages")
director := newDirector(normalBuilder)
normalHouse := director.buildHouse()
fmt.Printf("Normal House Door Type: %s\n", normalHouse.doorType)
fmt.Printf("Normal House Window Type: %s\n", normalHouse.windowType)
fmt.Printf("Normal House SwimPool: %s\n", normalHouse.swimPool)
fmt.Printf("Normal House Num Floor: %d\n", normalHouse.floor)
director.setBuilder(cottagesBuilder)
cottagesHouse := director.buildHouse()
fmt.Printf("\nCottage House Door Type: %s\n", cottagesHouse.doorType)
fmt.Printf("Cottage House Window Type: %s\n", cottagesHouse.windowType)
fmt.Printf("Cottage House SwimPool: %s\n", cottagesHouse.swimPool)
fmt.Printf("Cottage House Num Floor: %d\n", cottagesHouse.floor)
}
终端输出
建造者模式的代码拆分
1.项目的准备工作
找到 go 的 GOPATH
$ go env //可以查看 GOPATH
在 GOPATH 目录下创建3个文件夹
1.bin文件夹 -- 存放编译后的二进制文件
2.pkg文件夹 -- 存放编译后的库文件
3.src文件夹 -- 存放源码文件
2.创建文件夹
-- 在项目文件夹 builde_case 里创建新文件夹
builde -- 存放建造者的全部文件
3.接口文件 -- builde文件夹
文件1 -- ibuilder.go
package builde
// 建造者接口(泛指工人)
type IBuilder interface {
setWindowType()
setDoorType()
setNumFloor()
setSwimPool()
getHouse() House
}
func GetBuilder(builderType string) IBuilder {
if builderType == "normal" {
return newNormalBuilder()
}
if builderType == "cottages" {
return newCottagesBuilder()
}
return nil
}
4.结构体文件 -- builde文件夹
1.产品
文件1 -- house.go
package builde
// 房子(产品)
type House struct {
WindowType string
DoorType string
SwimPool string
Floor int
}
2.建造队
文件1 --normalbuilder.go
package builde
// 普通房子具体建造者(普通工人)
type NormalBuilder struct {
WindowType string
DoorType string
SwimPool string
Floor int
}
func newNormalBuilder() *NormalBuilder {
return &NormalBuilder{}
}
func (b *NormalBuilder) setWindowType() {
b.WindowType = "Wooden Window"
}
func (b *NormalBuilder) setDoorType() {
b.DoorType = "Wooden Door"
}
func (b *NormalBuilder) setNumFloor() {
b.Floor = 3
}
func (b *NormalBuilder) setSwimPool() {
b.SwimPool = "None"
}
func (b *NormalBuilder) getHouse() House {
return House{
DoorType: b.DoorType,
WindowType: b.WindowType,
SwimPool: b.SwimPool,
Floor: b.Floor,
}
}
文件2 -- cottagesbuilder.go
package builde
// 别墅具体建设者(别墅工人)
type CottagesBuilder struct {
WindowType string
DoorType string
SwimPool string
Floor int
}
func newCottagesBuilder() *CottagesBuilder {
return &CottagesBuilder{}
}
func (b *CottagesBuilder) setWindowType() {
b.WindowType = "Glass Window"
}
func (b *CottagesBuilder) setDoorType() {
b.DoorType = "Steel Security Door"
}
func (b *CottagesBuilder) setNumFloor() {
b.Floor = 1
}
func (b *CottagesBuilder) setSwimPool() {
b.SwimPool = "Swimming Pool"
}
func (b *CottagesBuilder) getHouse() House {
return House{
DoorType: b.DoorType,
WindowType: b.WindowType,
SwimPool: b.SwimPool,
Floor: b.Floor,
}
}
文件3 -- director.go
package builde
// 主管(工头)
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()
d.Builder.setSwimPool()
return d.Builder.getHouse()
}
5.主文件 -- main.go 在项目文件夹
package main
import (
"design/builde_case/builde"
"fmt"
)
// 具体工作
func main() {
normalBuilder := builde.GetBuilder("normal")
cottagesBuilder := builde.GetBuilder("cottages")
director := builde.NewDirector(normalBuilder)
normalHouse := director.BuildHouse()
fmt.Printf("Normal House Door Type: %s\n", normalHouse.DoorType)
fmt.Printf("Normal House Window Type: %s\n", normalHouse.WindowType)
fmt.Printf("Normal House SwimPool: %s\n", normalHouse.SwimPool)
fmt.Printf("Normal House Num Floor: %d\n", normalHouse.Floor)
director.SetBuilder(cottagesBuilder)
cottagesHouse := director.BuildHouse()
fmt.Printf("\nCottage House Door Type: %s\n", cottagesHouse.DoorType)
fmt.Printf("Cottage House Window Type: %s\n", cottagesHouse.WindowType)
fmt.Printf("Cottage House SwimPool: %s\n", cottagesHouse.SwimPool)
fmt.Printf("Cottage House Num Floor: %d\n", cottagesHouse.Floor)
}