Golang设计模式学习笔记--建造者模式

在软件开发中有时需要创建一个复杂的对象,这个对象有很多小对象按照一定的步骤组成,例如计算机是由主板、内存、cpu、硬盘、显卡等组件组成,采购员不可能自己组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司再安排技术人员组装计算机,再交给采购员

生活中这种例子也有很多,比如游戏中不同角色的性格、能力、脸型,体型、发型、服装等各有差异,汽车的方向盘,轮胎、发动机、轮胎、也有多钟多样。每封邮件的主题,内容附件等内容也各不相同。

建造者模式的定义

是指将一个复杂的对象的构造与表象分离,使得同样的构造过程可以创建不同的表示,他将变与不变分离,即使产品的组成部分是不变的,但是每一部分是可以灵活选择的。

建造者模式的优点

封装性好,构建和表示分离

扩展性好,各个不同的建造者相互独立,有利于系统的解耦

调用者不必知道产品的内部组成细节,建造者可以对创建过程逐步细化,也不会影响到其他模块

建造者模式的缺点

产品的组成部分必须相同,限制了其使用范围

如果产品的内部变化过大,则建造者也要同步进行修改,后期维护成本比较大

建造者模式和工厂模式关注点不同,建造者模式更关注零部件的组装过程,而工厂模式更关注的是创建过程。但是两者可以结合使用

这里可以理解为:每个零件需要工厂来生产,但是实际负责组装的工厂,这里叫做建造者。

建造者模式的要素

建造者模式由产品(Product)、指挥者(Director)、抽象创建者(Builder)、具体创建者(Concrete Builder)4个要素组成

具体代码分析

产品
包含getter setter方法

// Product 是产品 type Product struct { partA string partB string partC string } func (p *Product) PartA() string { return p.partA } func (p *Product) SetPartA(partA string) { p.partA = partA } func (p *Product) PartB() string { return p.partB } func (p *Product) SetPartB(partB string) { p.partB = partB } func (p *Product) PartC() string { return p.partC } func (p *Product) SetPartC(partC string) { p.partC = partC }

指挥者
包含一个建造函数Construct()返回产品

// Director 是指挥者 type Director struct { builder Builder } func (d *Director)Construct() interface{} { d.builder.newProduct() d.builder.buildPartA() d.builder.buildPartB() d.builder.buildPartC() return d.builder.getResult() } func NewDirector(builder Builder) *Director { return &Director{ builder: builder, } }

抽象建造者

// Builder 是一个抽象建造者 type Builder interface { // 创建新产品 newProduct() buildPartA() buildPartB() buildPartC() // 返回产品对象 getResult() interface{} }

具体建造者
实现Builder接口

// ConcreteBuilder 是具体的建造者 type ConcreteBuilder struct { product *Product } func (cb *ConcreteBuilder)newProduct() { cb.product = &Product{} } func (cb *ConcreteBuilder)buildPartA() { cb.product.SetPartA("A部分已构建") } func (cb *ConcreteBuilder) buildPartB() { cb.product.SetPartB("B部分已构建") } func (cb *ConcreteBuilder)buildPartC() { cb.product.SetPartC("C部分已构建") } // 返回产品对象 func (cb *ConcreteBuilder)getResult() interface{} { return cb.product }

实际调用

b:= &builder.ConcreteBuilder{} director := builder.NewDirector(b) product := director.Construct() 适用场景

相同的方法,不同的执行顺序,产生不同的结果。

多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。

产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。

初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

完整代码传送门

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyxffy.html