当前位置: 首页 > news >正文

GO设计模式——5、建造者模式(创建型)

目录

建造者模式(Builder Pattern)  

建造者模式的核心角色

优缺点

使用场景

注意事项

代码实现


建造者模式(Builder Pattern)  

       建造者模式(Builder Pattern)是将一个复杂对象构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

建造者模式的核心角色

        1、抽象建造者(Builder):是为创建一个Product对象的各个部件指定的抽象接口。

        2、具体建造者(ConcreteBuilder):实现Builder接口,构造和装配各个部件。

        3、指挥者(Director):是构建一个实用Builder接口的对象。一方面它隔离了客户与生产过程;另一方面它负责控制产品的生成过程。

        4、产品角色(Product):具体的产品

优缺点

(1)优点:

  • 分离构建过程和表示,使得构建过程更加灵活,可以构建不同的表示。
  • 可以更好地控制构建过程,隐藏具体构建细节。
  • 代码复用性高,可以在不同的构建过程中重复使用相同的建造者。

(2)缺点:

  • 如果产品的属性较少,建造者模式可能会导致代码冗余。
  • 建造者模式增加了系统的类和对象数量。

使用场景

        建造者模式在创建复杂对象时非常有用,特别是当对象的构建过程涉及多个步骤或参数时。它可以提供更好的灵活性和可维护性,同时使得代码更加清晰可读。

  • 需要生成的对象具有复杂的内部结构。
  • 需要生成的对象内部属性本身相互依赖

注意事项

        与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

代码实现

package mainimport ("errors""fmt"
)// Product内的参数
type ResourceParams struct {name     stringmaxTotal int64maxIdle  int64minIdle  int64
}// Product接口
type ResourceProduct interface {show()
}// 实际Product,有show函数
type RedisResourceProduct struct {resourceParams ResourceParams
}// show成员函数,用于显示product的参数内容
func (p *RedisResourceProduct) show() {fmt.Printf("Product的数据为 %+v ", p.resourceParams)
}// 资源类创建接口
type ResourceBuilder interface {setName(name string) ResourceBuildersetMaxTotal(maxTotal int64) ResourceBuildersetMaxIdle(maxIdle int64) ResourceBuildersetMinIdle(minIdle int64) ResourceBuildergetError() errorbuild() (p ResourceProduct)
}// 实际建造者
type RedisResourceBuilder struct {resourceParams ResourceParamserr            error
}// 设置名称
func (r *RedisResourceBuilder) setName(name string) ResourceBuilder {if name == "" {r.err = errors.New("name为空")return r}r.resourceParams.name = namefmt.Println("RedisResourceBuilder setName ", name)return r
}// 设置maxTotal值,值不能小于0
func (r *RedisResourceBuilder) setMaxTotal(maxTotal int64) ResourceBuilder {if maxTotal <= 0 {r.err = errors.New("maxTotal小于0")return r}r.resourceParams.maxTotal = maxTotalfmt.Println("RedisResourceBuilder setMaxTotal ", maxTotal)return r
}// 设置maxIdle值,值不能小于0
func (r *RedisResourceBuilder) setMaxIdle(maxIdle int64) ResourceBuilder {if maxIdle <= 0 {r.err = errors.New("maxIdle小于0")return r}r.resourceParams.maxIdle = maxIdlefmt.Println("RedisResourceBuilder setMaxIdle ", maxIdle)return r
}// 设置minIdle值,值不能小于0
func (r *RedisResourceBuilder) setMinIdle(minIdle int64) ResourceBuilder {if minIdle <= 0 {r.err = errors.New("minIdle小于0")return r}r.resourceParams.minIdle = minIdlefmt.Println("RedisResourceBuilder setMinIdle ", minIdle)return r
}// 获取错误信息
func (r *RedisResourceBuilder) getError() error {return r.err
}// 构建product: 1. 做参数校验  2. 根据参数生成product
func (r *RedisResourceBuilder) build() (p ResourceProduct) {// 校验逻辑放到这里来做,包括必填项校验、依赖关系校验、约束条件校验等if r.resourceParams.name == "" {r.err = errors.New("name为空")return}if !((r.resourceParams.maxIdle == 0 && r.resourceParams.minIdle == 0 && r.resourceParams.maxTotal == 0) ||(r.resourceParams.maxIdle != 0 && r.resourceParams.minIdle != 0 && r.resourceParams.maxTotal != 0)) {r.err = errors.New("数据需要保持一致")return}if r.resourceParams.maxIdle > r.resourceParams.maxTotal {r.err = errors.New("maxIdle > maxTotal")return}if r.resourceParams.minIdle > r.resourceParams.maxTotal || r.resourceParams.minIdle > r.resourceParams.maxIdle {r.err = errors.New("minIdle > maxTotal|maxIdle")return}fmt.Println("RedisResourceBuilder build")product := &RedisResourceProduct{resourceParams: r.resourceParams,}return product
}// 指挥者
type Director struct {
}// 指挥者控制建造过程
func (d *Director) construct(builder ResourceBuilder) ResourceProduct {resourceProduct := builder.setName("redis").setMinIdle(10).setMaxIdle(10).setMaxTotal(20).build()err := builder.getError()if err != nil {fmt.Println("构建失败,原因为" + err.Error())return nil}return resourceProduct
}func main() {builder := &RedisResourceBuilder{}director := &Director{}product := director.construct(builder)if product == nil {return}product.show()
}
http://www.lryc.cn/news/255093.html

相关文章:

  • 《LeetCode力扣练习》代码随想录——字符串(反转字符串II---Java)
  • WMMSE方法的使用笔记
  • MySQL核心知识点整理大全1-笔记
  • 理解输出电压纹波和噪声:来源与抑制
  • uni-app 微信小程序之好看的ui登录页面(二)
  • Textual Inversion
  • 笙默考试管理系统-MyExamTest----codemirror(47)
  • JVM中 Minor GC 和 Full GC 的区别
  • 二十一章(网络通信)
  • [linux运维] 利用zabbix监控linux高危命令并发送告警(基于Zabbix 6)
  • 手机升级到iOS15.8后无法在xcode(14.2)上真机调试
  • 安装TensorFlow2.12.0
  • elasticsearch 索引数据多了怎么办,如何调优,部署?
  • 人工智能企业引入S-SDLC,推动安全能力大跃升,保障AI技术体系深化落地
  • Docker的数据卷
  • 第二十一章总结博客
  • 学习php中使用composer下载安装firebase/php-jwt 以及调用方法
  • 『TypeScript』深入理解变量声明、函数定义、类与接口及泛型
  • 如何优雅使用 vue-html2pdf 插件生成pdf报表
  • C语言第十六集(前)
  • Makefile语法
  • 用户案例|Milvus 助力 Credal.AI 实现 GenAI 安全与可控
  • MySQL三 | 多表查询
  • PostgreSQL 索引介绍和使用事项
  • MySQL注入攻防详解:保障数据库安全的最佳实践
  • ubuntu or MacOS 源码安装 fmt fmtlib
  • vue watch
  • 异常检测 | 基于孤立森林(Isolation Forest)的数据异常数据检测(结合t-SNE降维可视化)
  • 【深度学习】一维数组的聚类
  • 100多种视频转场素材|专业胶片,抖动,光效电影转场特效PR效果预设