三、建造者模式

2024-08-29 22:28
文章标签 模式 建造

本文主要是介绍三、建造者模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

构造者模式(Builder Pattern)使用简单的对象一步一步构建成一个复杂的对象。这种设计模式属于创建者模式,它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。例如,计算机是由 CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。

主要组成部分:

  1. 产品(Product)

    • 需要构建的复杂对象,通常是一个包含多个属性的类。
  2. 构造器接口(Builder)

    • 定义了构建产品的接口,通常包括设置产品各个部分的方法。
  3. 具体构建者(Concrete Builder)

    • 实现了构造器接口,负责具体产品的构建过程。通常还提供一个方法用于获取最终产品。
  4. 指挥者(Director)

    • 负责管理构建过程,调用构建者的具体方法来构建产品。
GO: 

其实在 Golang 中对于创建类参数比较多的对象的时候,我们常见的做法是必填参数直接传递,可选参数通过传递可变的方法进行创建。

方式一:使用 Go 编写建造者模式的代码其实会很长,这些是它的一个缺点,所以如果不是参数的校验逻辑很复杂的情况下一般我们在 Go 中不会采用这种方式,而会采用后面的另外一种方式
package builderimport "fmt"const (defaultMaxTotal = 10defaultMaxIdle  = 9defaultMinIdle  = 1
)// ResourcePoolConfig resource pool
type ResourcePoolConfig struct {name     stringmaxTotal intmaxIdle  intminIdle  int
}// ResourcePoolConfigBuilder 用于构建 ResourcePoolConfig
type ResourcePoolConfigBuilder struct {name     stringmaxTotal intmaxIdle  intminIdle  int
}// SetName SetName
func (b *ResourcePoolConfigBuilder) SetName(name string) error {if name == "" {return fmt.Errorf("name can not be empty")}b.name = namereturn nil
}// SetMinIdle SetMinIdle
func (b *ResourcePoolConfigBuilder) SetMinIdle(minIdle int) error {if minIdle < 0 {return fmt.Errorf("max tatal cannot < 0, input: %d", minIdle)}b.minIdle = minIdlereturn nil
}// SetMaxIdle SetMaxIdle
func (b *ResourcePoolConfigBuilder) SetMaxIdle(maxIdle int) error {if maxIdle < 0 {return fmt.Errorf("max tatal cannot < 0, input: %d", maxIdle)}b.maxIdle = maxIdlereturn nil
}// SetMaxTotal SetMaxTotal
func (b *ResourcePoolConfigBuilder) SetMaxTotal(maxTotal int) error {if maxTotal <= 0 {return fmt.Errorf("max tatal cannot <= 0, input: %d", maxTotal)}b.maxTotal = maxTotalreturn nil
}// Build Build
func (b *ResourcePoolConfigBuilder) Build() (*ResourcePoolConfig, error) {if b.name == "" {return nil, fmt.Errorf("name can not be empty")}// 设置默认值if b.minIdle == 0 {b.minIdle = defaultMinIdle}if b.maxIdle == 0 {b.maxIdle = defaultMaxIdle}if b.maxTotal == 0 {b.maxTotal = defaultMaxTotal}if b.maxTotal < b.maxIdle {return nil, fmt.Errorf("max total(%d) cannot < max idle(%d)", b.maxTotal, b.maxIdle)}if b.minIdle > b.maxIdle {return nil, fmt.Errorf("max idle(%d) cannot < min idle(%d)", b.maxIdle, b.minIdle)}return &ResourcePoolConfig{name:     b.name,maxTotal: b.maxTotal,maxIdle:  b.maxIdle,minIdle:  b.minIdle,}, nil
}
func TestBuilder(t *testing.T) {tests := []struct {name    stringbuilder *ResourcePoolConfigBuilderwant    *ResourcePoolConfigwantErr bool}{{name: "name empty",builder: &ResourcePoolConfigBuilder{name:     "",maxTotal: 0,},want:    nil,wantErr: true,},{name: "maxIdle < minIdle",builder: &ResourcePoolConfigBuilder{name:     "test",maxTotal: 0,maxIdle:  10,minIdle:  20,},want:    nil,wantErr: true,},{name: "success",builder: &ResourcePoolConfigBuilder{name: "test",},want: &ResourcePoolConfig{name:     "test",maxTotal: defaultMaxTotal,maxIdle:  defaultMaxIdle,minIdle:  defaultMinIdle,},wantErr: false,},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {got, err := tt.builder.Build()fmt.Printf("Build() error = %v, wantErr %v\n", err, tt.wantErr)fmt.Println(got)})}}

方式二:GO常用的参数传递方法 
package builderimport "fmt"const (defaultMaxTotal = 10defaultMaxIdle  = 9defaultMinIdle  = 1
)// ResourcePoolConfig resource pool
type ResourcePoolConfig struct {name     stringmaxTotal intmaxIdle  intminIdle  int
}// ResourcePoolConfigOption resource pool
type ResourcePoolConfigOption struct {maxTotal intmaxIdle  intminIdle  int
}// ResourcePoolConfigOptFunc to set option
type ResourcePoolConfigOptFunc func(option *ResourcePoolConfigOption)// NewResourcePoolConfig NewResourcePoolConfig
func NewResourcePoolConfig(name string, opts ...ResourcePoolConfigOptFunc) (*ResourcePoolConfig, error) {if name == "" {return nil, fmt.Errorf("name can not be empty")}option := &ResourcePoolConfigOption{maxTotal: 10,maxIdle:  9,minIdle:  1,}for _, opt := range opts {opt(option)}if option.maxTotal < 0 || option.maxIdle < 0 || option.minIdle < 0 {return nil, fmt.Errorf("args err, option: %v", option)}if option.maxTotal < option.maxIdle || option.minIdle > option.maxIdle {return nil, fmt.Errorf("args err, option: %v", option)}return &ResourcePoolConfig{name:     name,maxTotal: option.maxTotal,maxIdle:  option.maxIdle,minIdle:  option.minIdle,}, nil
}
func TestBuilder(t *testing.T) {type args struct {name stringopts []ResourcePoolConfigOptFunc}tests := []struct {name    stringargs    argswant    *ResourcePoolConfigwantErr bool}{{name: "name empty",args: args{name: "",},want:    nil,wantErr: true,},{name: "success",args: args{name: "test",opts: []ResourcePoolConfigOptFunc{func(option *ResourcePoolConfigOption) {option.minIdle = 2},func(option *ResourcePoolConfigOption) {option.maxTotal = 100},},},want: &ResourcePoolConfig{name:     "test",maxTotal: 10,maxIdle:  9,minIdle:  2,},wantErr: false,},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {got, err := NewResourcePoolConfig(tt.args.name, tt.args.opts...)require.Equalf(t, tt.wantErr, err != nil, "error = %v, wantErr %v", err, tt.wantErr)assert.Equal(t, tt.want, got)})}
}

JAVA:

...未完待续

这篇关于三、建造者模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1119024

相关文章

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

大数据spark3.5安装部署之local模式详解

《大数据spark3.5安装部署之local模式详解》本文介绍了如何在本地模式下安装和配置Spark,并展示了如何使用SparkShell进行基本的数据处理操作,同时,还介绍了如何通过Spark-su... 目录下载上传解压配置jdk解压配置环境变量启动查看交互操作命令行提交应用spark,一个数据处理框架

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

迭代器模式iterator

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/iterator 不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试