设计模式-建造者模式(Go语言描述)

版权声明:本文来自Loader's Blog,未经博主允许不得转载。 https://blog.csdn.net/qibin0506/article/details/51283853

在上一篇博客设计模式-装饰者模式中我们介绍了如何在golang中实现装饰者模式,今天我们接着上篇博客继续设计模式系列文章,今天还是来看一个简单的设计模式-建造者模式

介绍

相信做过android的同学对建造者模式还是比较熟悉的, 一定用过开源的图片加载框架ImageLoader吧, 在ImageLoader的配置中我们就使用了建造者模式, 那什么是建造者模式呢?来看一下定义:

将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。

建造者模式中有一下几个角色需要我们熟悉:

  1. Product 这是我们要创建的复杂对象(一般都是很复杂的对象才需要使用建造者模式)。
  2. Builder 抽象的一个东西, 主要是用来规范我们的建造者的。
  3. ConcreteBuilder 具体的Builder实现, 这是今天的重点,主要用来根据不用的业务来完成要创建对象的组建的创建。
  4. Director 这个的作用是规范复杂对象的创建流程。

在来看看创建模式的结构图:

好了,了解了什么是建造者以及建造者中涉及的几个角色,下面我们就来用代码实现一下建造者模式,根据上面提到的几个角色,我们依依用代码来实现它。 今天我们用一个游戏中的角色创建的事例来展示代码,我们这个游戏角色很简单,仅仅包含名称和使用的武器两个字段。

创建复杂对象

首先我们来创建具体的游戏人物类

type Character struct {
  Name string
  Arms string
}

func (p *Character) SetName(name string) {
  p.Name = name
}

func (p *Character) SetArms(arms string) {
  p.Arms = arms
}

func (p Character) GetName() string {
  return p.Name
}

func (p Character) GetArms() string {
  return p.Arms
}

这个类很简单,除了包含我们上面提到了名称和使用的武器两个字段外,剩下的代码仅仅是为这两个字段提供getter和setter方法了,这里不多说了,下面我们就根据这个类来创建一个建造者接口。

实现抽象建造者接口

type Builder interface {
  SetName(name string) Builder
  SetArms(arms string) Builder
  Build() *Character
}

前两个方法是我们根据游戏人物类设计出来的,最后一个Build方法用来返回我们创建的游戏人物对象。

创建具体的创建者类

下面我们就来根据上面定义的接口来实现一个具体的创建者类,

type CharacterBuilder struct {
  character *Character
}

func (p *CharacterBuilder) SetName(name string) Builder {
  if p.character == nil {
    p.character = &Character{}
  }
  p.character.SetName(name)
  return p
}

func (p *CharacterBuilder) SetArms(arms string) Builder {
  if p.character == nil {
    p.character = &Character{}
  }
  p.character.SetArms(arms)
  return p
}

func (p *CharacterBuilder) Build() *Character {
  return p.character
}

这个结构体实现了上面定义的接口Builder的所有方法,所以它实现了Builder接口,并且它还拥有一个Character的变量,我们就是用来创建这个类型的实例。Build方法最后返回我们创建的游戏角色对象。

Director的实现

上面说过,Director的作用主要是规范对象的组件的创建流程,来看看它的实现吧:

type Director struct {
  builder Builder
}

func (p Director) Create(name string, arms string) *Character {
  return p.builder.SetName(name).SetArms(arms).Build()
}

他需要一个Builder的实例,所以我们在创建Director的时候需要定义一个Builder的具体实现,Director只有一个方法-Create方法,我们通过调用Create方法来根据参数创建具体的游戏角色。
最后我们再来看看如何使用:

func main() {
  var builder Builder = &CharacterBuilder {}
  var director *Director = &Director {builder: builder}
  var character *Character = director.Create("loader", "AK47")
  fmt.Println(character.GetName() + "," + character.GetArms())
}

首先我们创建了一个Builder具体实现的实例,接着将他给Director的实例,最后我们通过调用DirectorCreate方法来完成具体游戏角色的创建。最后我们再强调一点,什么时候使用创建者模式? 当一个对象并不是很复杂的时候不太适用创建者模式,当我们需要创建的对象特别复杂的时候才考虑使用创建者模式实现。

代码放github上了,欢迎star: https://github.com/qibin0506/go-designpattern

阅读更多

没有更多推荐了,返回首页