设计模式之建造者模式

设计模式之建造者模式

建造者模式又称为生成器模式,建造者模式为客户端返回的不是一个简单的产品,而是一个由多个部件组成的复杂产品

概述

建造者模式是较为复杂的创建型模式,它将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所创建的建造者类型即可。建造者关注如何一步步创建一个复杂对象,不同的建造者定义了不同的创建过程,而且具体的建造者相互独立,增加新的建造者也无须修改已有的代码,具有比较好的拓展性,建造者允许用户只通过制定复杂对象的类型和内容就可以构建他们,用户不需要知道内部的具体细节

定义

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式

建造者模式包含4个角色

  1. Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法:一类是builderPartX(),用于创建复杂对象的各个部件,另一类方法是getResult(),用于返回复杂对象。
  2. ConcreteBuilder(具体建造者):他实现了Builder接口,实现了各个部件的具体构造和装配方法,定义并明确了其所创建的复杂对象,也提供一个方法返回创建好的复杂产品对象
  3. Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义其装配过程
  4. Director(指挥者): 它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造,客户端一般只需要和指挥者交互

什么是复杂对象?复杂对象就是包含多个成员变量的对象

组装电脑

我们以组装电脑为例子,假设我们需要组装不同CPU,内存,硬盘,以及显卡的电脑,我们可以把这个过程模拟成建造者模式,以下是代码实现

package builder

type Builder interface {
   InstallCpu()
   InstallMemory()
   InstallHardDisk()
   InstallMobo()
   InstallGpu()

   GetComputer() Computer
}

type Computer struct {
   Cpu      string // cpu
   Memory   string // 内存
   HardDisk string // 硬盘
   Mobo     string // 主板
   Gpu      string // 显卡

}

type Director struct {
   ComputerBuilder Builder
}

func NewDirector(computerBuilder Builder) *Director {
   return &Director{
      ComputerBuilder: computerBuilder,
   }
}

func (d *Director) Construct() Computer {
   d.ComputerBuilder.InstallCpu()
   d.ComputerBuilder.InstallMobo()
   d.ComputerBuilder.InstallHardDisk()
   d.ComputerBuilder.InstallMemory()
   d.ComputerBuilder.InstallGpu()
   return d.ComputerBuilder.GetComputer()

}

// OfficeComputer 办公电脑
type OfficeComputer struct {
   Computer Computer
}

// GameComputer 游戏电脑
type GameComputer struct {
   Computer Computer
}

func NewOfficeComputer() *OfficeComputer {
   return &OfficeComputer{
      Computer: Computer{},
   }
}

func NewGameComputer() *GameComputer {
   return &GameComputer{
      Computer: Computer{},
   }
}

func (o *OfficeComputer) InstallCpu() {
   o.Computer.Cpu = "Intel H610"
}

func (o *OfficeComputer) InstallMemory() {
   o.Computer.Memory = "8G"
}

func (o *OfficeComputer) InstallHardDisk() {
   o.Computer.HardDisk = "256G"
}

func (o *OfficeComputer) InstallMobo() {
   o.Computer.Mobo = "华硕(ASUS)PRIME H610M-A D4主板"
}
func (o *OfficeComputer) InstallGpu() {
   o.Computer.Gpu = "核显"
}
func (o *OfficeComputer) GetComputer() Computer {
   return o.Computer
}

func (g *GameComputer) InstallCpu() {
   g.Computer.Cpu = "i5-12400"
}

func (g *GameComputer) InstallMemory() {
   g.Computer.Memory = "16G"
}

func (g *GameComputer) InstallHardDisk() {
   g.Computer.HardDisk = "500G"
}
func (g *GameComputer) InstallMobo() {
   g.Computer.Mobo = "华硕B660M电竞主板"
}
func (g *GameComputer) InstallGpu() {
   g.Computer.Gpu = "RTX3050"
}
func (g *GameComputer) GetComputer() Computer {
   return g.Computer
}

这里的Builder,就是一个接口,定义了一些组装的方法,同时也定义了一个GetComputer来获取最终得到的电脑

type Builder interface {
   InstallCpu()
   InstallMemory()
   InstallHardDisk()
   InstallMobo()
   InstallGpu()

   GetComputer() Computer
}

同时定一个结构体Computer,里面包含了许多的属性

type Computer struct {
   Cpu      string // cpu
   Memory   string // 内存
   HardDisk string // 硬盘
   Mobo     string // 主板
   Gpu      string // 显卡

}

还定义了OfficeComputer以及GameComputer来作为建造者,实现Builder的方法

// OfficeComputer 办公电脑
type OfficeComputer struct {
   Computer Computer
}

// GameComputer 游戏电脑
type GameComputer struct {
   Computer Computer
}

func NewOfficeComputer() *OfficeComputer {
   return &OfficeComputer{
      Computer: Computer{},
   }
}

func NewGameComputer() *GameComputer {
   return &GameComputer{
      Computer: Computer{},
   }
}

func (o *OfficeComputer) InstallCpu() {
   o.Computer.Cpu = "Intel H610"
}

func (o *OfficeComputer) InstallMemory() {
   o.Computer.Memory = "8G"
}

func (o *OfficeComputer) InstallHardDisk() {
   o.Computer.HardDisk = "256G"
}

func (o *OfficeComputer) InstallMobo() {
   o.Computer.Mobo = "华硕(ASUS)PRIME H610M-A D4主板"
}
func (o *OfficeComputer) InstallGpu() {
   o.Computer.Gpu = "核显"
}
func (o *OfficeComputer) GetComputer() Computer {
   return o.Computer
}

func (g *GameComputer) InstallCpu() {
   g.Computer.Cpu = "i5-12400"
}

func (g *GameComputer) InstallMemory() {
   g.Computer.Memory = "16G"
}

func (g *GameComputer) InstallHardDisk() {
   g.Computer.HardDisk = "500G"
}
func (g *GameComputer) InstallMobo() {
   g.Computer.Mobo = "华硕B660M电竞主板"
}
func (g *GameComputer) InstallGpu() {
   g.Computer.Gpu = "RTX3050"
}
func (g *GameComputer) GetComputer() Computer {
   return g.Computer
}

最后,我们定义了一个指挥者,用来做最后的对象创建

type Director struct {
   ComputerBuilder Builder
}

func NewDirector(computerBuilder Builder) *Director {
   return &Director{
      ComputerBuilder: computerBuilder,
   }
}

func (d *Director) Construct() Computer {
   d.ComputerBuilder.InstallCpu()
   d.ComputerBuilder.InstallMobo()
   d.ComputerBuilder.InstallHardDisk()
   d.ComputerBuilder.InstallMemory()
   d.ComputerBuilder.InstallGpu()
   return d.ComputerBuilder.GetComputer()
测试
package builder

import (
   "fmt"
   "testing"
)

func TestDirector_Construct(t *testing.T) {
   officeComputerBuilder := NewOfficeComputer()
   officeDirector := NewDirector(officeComputerBuilder)
   computer := officeDirector.Construct()
   fmt.Println(computer)

   gameComputerBuilder := NewGameComputer()
   gameDirector := NewDirector(gameComputerBuilder)
   gameComputer := gameDirector.Construct()
   fmt.Println(gameComputer)
}

// 
// === RUN   TestDirector_Construct
// {Intel H610 8G 256G 华硕(ASUS)PRIME H610M-A D4主板 核显}
// {i5-12400 16G 500G 华硕B660M电竞主板 RTX3050}
// --- PASS: TestDirector_Construct (0.00s)
// PASS

总结

优点
  1. 在建造者模式中,客户端不必知道产品内部的创建细节,将产品本身和产品的创建过程解耦,使得创建过程相同可以创建不同的产品对象
  2. 每一个具体的建造者都相对独立,而与其他的具体建造者无关,增加新的建造者无需修改原有的建造者的代码
  3. 可以更加精细的控制产品的创建过程,将复杂的产品的创建步骤分解在不同的方法中,是的创建过程更加清晰
缺点
  1. 建造者创建的产品一般具有较多的共同电,如果产品之间的差异性很大,则不适合
  2. 如果产品内部结构复杂且多变,可能需要定义很多的建造者,会使得系统变得庞大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值