GoLang设计模式01 - 生成器模式

生成器模式是什么

生成器模式也叫做建造者模式,是一种创建型的设计模式, 使你能够分步骤创建复杂对象。

为什么要用生成器模式

假设有这样一个复杂对象, 在对其进行构造时需要对诸多成员变量和嵌套对象进行复杂的初始化工作。这些初始化代码通常深藏于一个包含众多参数且让人基本看不懂的构造函数中。而且在很多时候的程序调用中只需要少部分的成员参数。这个时候如果我们写一个复杂的构造函数不仅不利于维护,而且很多成员参数用不到是一种浪费。

生成器模式怎么实现

首先是我们的目标即:创建的具体的产品,然后我们写两个具体的生成器来实现这个产品,最后是生成器接口来抽象实现的方法。

下面是UML类图:

 

 

代码大致如下。

house.go:

1 package main
2  
3 type house struct {
4     windowType string
5     doorType   string
6     floor      int
7 }

iBuilder.go:

 1 package main
 2 //抽象层
 3 type iBuilder interface {
 4     setWindowType()
 5     setDoorType()
 6     setNumFloor()
 7     getHouse() house
 8 }
 9 
10 //getBuilder类似简单工厂模式,略有区别,简单工厂模式常规配备一个工厂类(结构体),类下有一个create方法,ps:什么是简单工厂模式?
11 //简单工厂模式是一种创建型设计模式,由于Go本身是没有构造函数的,一般而言我们采用NewName的方式创建对象/接口,当它返回的是接口的时候,其实就是简单工厂模式
12 func getBuilder(builderType string) iBuilder {
13     if builderType == "cabin" {
14         return &cabinBuilder{}
15     }
16     if builderType == "igloo" {
17         return &iglooBuilder{}
18     }
19     return nil
20 }

iglooBuilder.go

 1 package main
 2  
 3 type iglooBuilder struct {
 4     house//这叫结构体内嵌,是为了直接调用house它的属性和方法
 5 }
 6  
 7 func newIglooBuilder() *iglooBuilder {
 8     return &iglooBuilder{}
 9 }
10  
11 func (b *iglooBuilder) setWindowType() {
12     b.windowType = "Ice Window"
13 }
14  
15 func (b *iglooBuilder) setDoorType() {
16     b.doorType = "Ice Door"
17 }
18  
19 func (b *iglooBuilder) setNumFloor() {
20     b.floor = 1
21 }
22  
23 func (b *iglooBuilder) getHouse() house {
24     return b.house
25 }

cabinBuilder.go

 1 package main
 2  
 3 type cabinBuilder struct {
 4     house
 5 }
 6  
 7 func newCabinBuilder() *cabinBuilder {
 8     return &cabinBuilder{}
 9 }
10  
11 func (b *cabinBuilder) setWindowType() {
12     b.windowType = "Wooden Window"
13 }
14  
15 func (b *cabinBuilder) setDoorType() {
16     b.doorType = "Wooden Door"
17 }
18  
19 func (b *cabinBuilder) setNumFloor() {
20     b.floor = 2
21 }
22  
23 func (b *cabinBuilder) getHouse() house {
24     return b.house
25 }

director.go主管类(可选)

 1 package main
 2  
 3 type director struct {
 4     builder iBuilder
 5 }
 6  
 7 func newDirector(b iBuilder) *director {
 8     return &director{
 9         builder: b,
10     }
11 }
12  
13 func (d *director) setBuilder(b iBuilder) {
14     d.builder = b
15 }
16  
17 func (d *director) buildHouse() house {
18     d.builder.setDoorType()
19     d.builder.setWindowType()
20     d.builder.setNumFloor()
21     return d.builder.getHouse()
22 }

最后是main方法:

 1 package main
 2  
 3 import (
 4     "fmt"
 5 )
 6  
 7 func main() {
 8     cabinBuilder := getBuilder("cabin")
 9     iglooBuilder := getBuilder("igloo")
10  
11     director := newDirector(cabinBuilder)
12     cabinHouse := director.buildHouse()
13  
14     fmt.Printf("Cabin House Door Type: %s\n", cabinHouse.doorType)
15     fmt.Printf("Cabin House Window Type: %s\n", cabinHouse.windowType)
16     fmt.Printf("Cabin House Num Floor: %d\n", cabinHouse.floor)
17  
18     director.setBuilder(iglooBuilder)
19     iglooHouse := director.buildHouse()
20  
21     fmt.Printf("\nIgloo House Door Type: %s\n", iglooHouse.doorType)
22     fmt.Printf("Igloo House Window Type: %s\n", iglooHouse.windowType)
23     fmt.Printf("Igloo House Num Floor: %d\n", iglooHouse.floor)
24 }

 

优点

  1. 你可以分步创建对象, 或暂缓创建步骤。
  2. 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  3. 具体的建造者相互独立,因此可以对建造的过程逐步细化,而不会对其他模块产生任何影响。

缺点

  1. 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  2. 如果产品内部发生变化 , 建造者也要相应修改。
posted @ 2023-04-20 17:00  格局打得开  阅读(167)  评论(0)    收藏  举报