前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 设计模式-建造者模式

Go 设计模式-建造者模式

作者头像
王小明_HIT
发布2021-07-27 16:32:50
3030
发布2021-07-27 16:32:50
举报
文章被收录于专栏:程序员奇点程序员奇点

设计模式

建造者模式

工厂模式用来创建不同、但是类型相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定哪种类型的对象,建造者模式是用来构建一种复杂对象,可以通过设置不同的可选参数,定制化创建不同的对象,

应用场景

  • 把类的必填属性放在构造函数中,强制创建的时候设置,如果必填属性很多,这些必填属性都需要放到构造函数中设置,那构造函数就会出现参数列表很长的问题。如果我们把必填属性通过 set() 方法设置,那校验这些属性是否填写的逻辑又无处安放。
  • 如果类属性之间有一定的依赖关系或者约束条件,我们继续用构造函数配合 set() 方法设计思路,那这些依赖关系或者约束条件又无处安放。
  • 如果我们希望创建不可变对象,也就是说,对象在创建好之后,就不能再修改内部的属性值,要实现这个功能,就不能暴露 set 方法,构造函数配合 set() 方法就不合适了。

代码例子

builder.go

代码语言:javascript
复制
package builder

//Builder 生成器接口
type Builder interface {
 Part1()
 Part2()
 Part3()
}

type Director struct {
 builder Builder
}

// NewDirector ...
func NewDirector(builder Builder) *Director {
 return &Director{
  builder: builder,
 }
}

//Construct Product
func (d *Director) Construct() {
 d.builder.Part1()
 d.builder.Part2()
 d.builder.Part3()
}

type Builder1 struct {
 result string
}

func (b *Builder1) Part1() {
 b.result += "1"
}

func (b *Builder1) Part2() {
 b.result += "2"
}

func (b *Builder1) Part3() {
 b.result += "3"
}

func (b *Builder1) GetResult() string {
 return b.result
}

type Builder2 struct {
 result int
}

func (b *Builder2) Part1() {
 b.result += 1
}

func (b *Builder2) Part2() {
 b.result += 2
}

func (b *Builder2) Part3() {
 b.result += 3
}

func (b *Builder2) GetResult() int {
 return b.result
}

builder_test.go

代码语言:javascript
复制
package builder

import "testing"

func TestBuilder1(t *testing.T) {
 builder := &Builder1{}
 director := NewDirector(builder)
 director.Construct()
 res := builder.GetResult()
 if res != "123" {
  t.Fatalf("Builder1 fail expect 123 acture %s", res)
 }
}

func TestBuilder2(t *testing.T) {
 builder := &Builder2{}
 director := NewDirector(builder)
 director.Construct()
 res := builder.GetResult()
 if res != 6 {
  t.Fatalf("Builder2 fail expect 6 acture %d", res)
 }
}

再看个例子

代码语言:javascript
复制
type Options struct {
 ConnTimeout time.Duration
 ReadTimeout time.Duration
 RetryTime   int32
}

// builder 模式
func (opt *Options) build() (err error) {
 // 校验逻辑
 if opt.ReadTimeout < opt.ConnTimeout {
  err = errors.New("error params")
  return
 }
 return
}
// 设置属性 ConnTimeOut
func (opt *Options) setConnTimeout(timeout time.Duration) *Options {
 opt.ConnTimeout = timeout
 return opt
}
// 设置属性 ReadTimeOut
func (opt *Options) setReadTimeout(timeout time.Duration) *Options {
 opt.ReadTimeout = timeout
 return opt
}
// 设置属性 retryTime
func (opt *Options) setRetryTime(times int32) *Options {
 opt.RetryTime = times
 return opt
}

builder_test.go

代码语言:javascript
复制
package main

import "testing"

func Build() {
 opt := &Options{}
 err := opt.
  setConnTimeout(100 * time.Second).
  setReadTimeout(1000 * time.Second).
  setRetryTime(1).
  build()
 if err != nil {
  panic(err)
 }
 fmt.Printf("BuildV1: %+v\n", opt)
}

func TestAppDemo(t *testing.T) {
 Build()
}

参考资料

  • https://github.com/senghoo/golang-design-pattern
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 设计模式
  • 建造者模式
  • 应用场景
    • 代码例子
      • 参考资料
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档