一起学习 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

优缺点

优点:


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


缺点:


  • 由于该模式需要新增多个类, 因此代码整体复杂程度会有所增加。
相关文章
|
9天前
|
程序员 Go PHP
为什么大部分的 PHP 程序员转不了 Go 语言?
【9月更文挑战第8天】大部分 PHP 程序员难以转向 Go 语言,主要因为:一、编程习惯与思维方式差异,如语法风格和编程范式;二、学习成本高,需掌握新知识体系且面临项目压力;三、职业发展考量,现有技能价值及市场需求不确定性。学习新语言虽有挑战,但对拓宽职业道路至关重要。
39 10
|
8天前
|
Go API 开发者
深入探讨:使用Go语言构建高性能RESTful API服务
在本文中,我们将探索Go语言在构建高效、可靠的RESTful API服务中的独特优势。通过实际案例分析,我们将展示Go如何通过其并发模型、简洁的语法和内置的http包,成为现代后端服务开发的有力工具。
|
10天前
|
算法 程序员 Go
PHP 程序员学会了 Go 语言就能唬住面试官吗?
【9月更文挑战第8天】学会Go语言可提升PHP程序员的面试印象,但不足以 solely “唬住” 面试官。学习新语言能展现学习能力、拓宽技术视野,并增加就业机会。然而,实际项目经验、深入理解语言特性和综合能力更为关键。全面展示这些方面才能真正提升面试成功率。
33 10
|
9天前
|
编译器 Go
go语言学习记录(关于一些奇怪的疑问)有别于其他编程语言
本文探讨了Go语言中的常量概念,特别是特殊常量iota的使用方法及其自动递增特性。同时,文中还提到了在声明常量时,后续常量可沿用前一个值的特点,以及在遍历map时可能遇到的非顺序打印问题。
|
7天前
|
存储 监控 数据可视化
Go 语言打造公司监控电脑的思路
在现代企业管理中,监控公司电脑系统对保障信息安全和提升工作效率至关重要。Go 语言凭借其高效性和简洁性,成为构建监控系统的理想选择。本文介绍了使用 Go 语言监控系统资源(如 CPU、内存)和网络活动的方法,并探讨了整合监控数据、设置告警机制及构建可视化界面的策略,以满足企业需求。
24 1
|
23小时前
|
Shell Go API
Go语言grequests库并发请求的实战案例
Go语言grequests库并发请求的实战案例
|
4月前
|
JSON JavaScript Go
Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
掌握 Go 语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解 Go 基础知识的好起点是查阅 Go 官方文档
883 2
|
11月前
|
自然语言处理 Java Go
Go语言学习之函数
Go语言学习之函数
26 0
|
4月前
|
Java Go 数据安全/隐私保护
Go语言学习7-函数类型
本篇 Huazie 向大家介绍 Go 语言的函数类型
49 1
Go语言学习7-函数类型
|
Go API
Go学习——runtime.Caller()函数
Go学习——runtime.Caller()函数
223 0