一起学习 Go 语言设计模式之建造者模式(下)

简介: 在设计模式中,建造者模式就是解决如何将这些部件组装成一辆完整的汽车并返回给用户的设计模式。建造者模式为客户端返回的不是一个简单的产品,而是一个由多个部件组成的复杂产品。

Go 代码示例

代码组织结构如下:


image.png


  1. 首先创建 house.go 文件, 建立 House 这个产品基类,代码如下;
package main
type House struct {
  windowType string
  doorType   string
  swimPool   string
  floor      int
}


正像前文所说一眼,房子有窗户、门、游泳池、楼层等部分组成。


  1. 然后创建抽象创建者 iBuilder.go 文件,也是我们的建造者接口,分别定义 4 个 set  和 1 个 getHouse()  方法,代码如下:
package main
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
}


  1. 新建具体建造者:普通房子 normalBuilder.go,在这个文件中,因为 Go 语言没有继承的概念,所以也需要我们定义跟 House 相同的结构体,然后实现 normalHouse 的构建 :
package main
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,
  }
}


  1. 跟上一步同理,新建别墅具体建设者 cottagesBuilder.go 文件,代码如下:
package main
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,
  }
}
  1. 新建主管 director.go ,主管结构体内也是抽象建造者,其次主管有着 setBuilder()buildHouse() 的职责,最后主管负责安排负责对象的建造次序,比如先确定门、窗、楼层,再考虑是否需要加装泳池。最终代码如下:
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()
  d.builder.setSwimPool()
  return d.builder.getHouse()
}


6.新建一个 main.go 文件,测试我们的创建者模式是否正确:

package main
import (
  "fmt"
)
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 run .


这是输出结果图:


image.png

优缺点

优点:


  • 你可以分步创建对象, 暂缓创建步骤或递归运行创建步骤。
  • 生成不同形式的产品时, 你可以复用相同的制造代码。
  • 单一职责原则。 你可以将复杂构造代码从产品的业务逻辑中分离出来。


缺点:


  • 由于该模式需要新增多个类, 因此代码整体复杂程度会有所增加。
相关文章
|
18天前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
29 7
|
18天前
|
Go 开发工具
百炼-千问模型通过openai接口构建assistant 等 go语言
由于阿里百炼平台通义千问大模型没有完善的go语言兼容openapi示例,并且官方答复assistant是不兼容openapi sdk的。 实际使用中发现是能够支持的,所以自己写了一个demo test示例,给大家做一个参考。
|
18天前
|
程序员 Go
go语言中结构体(Struct)
go语言中结构体(Struct)
93 71
|
17天前
|
存储 Go 索引
go语言中的数组(Array)
go语言中的数组(Array)
100 67
|
18天前
|
存储 Go
go语言中映射
go语言中映射
32 11
|
19天前
|
Go 索引
go语言修改元素
go语言修改元素
26 6
|
10天前
|
Go 数据安全/隐私保护 UED
优化Go语言中的网络连接:设置代理超时参数
优化Go语言中的网络连接:设置代理超时参数
|
20天前
|
Go 索引
go语言for遍历数组或切片
go语言for遍历数组或切片
90 62
|
22天前
|
并行计算 安全 Go
Go语言中的并发编程:掌握goroutines和channels####
本文深入探讨了Go语言中并发编程的核心概念——goroutine和channel。不同于传统的线程模型,Go通过轻量级的goroutine和通信机制channel,实现了高效的并发处理。我们将从基础概念开始,逐步深入到实际应用案例,揭示如何在Go语言中优雅地实现并发控制和数据同步。 ####