构建者模式也是一种创建型的设计模式,该模式将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的对象。大白话就是,构建者模式,从输出角度看依然是创建个对象实例,但是构建者模式更关注创建的细节,或者说一个对象的创建可以拆分为多个步骤,所有的步骤完成才创建出这个对象实例,而对于之前分享的工厂模式系列,那些都是偏重于创建简单的实例,侧重点不一样。
下面看看与工厂模式的区别:
- 1.工厂模式适合创建一样的简单实例,不注重构建细节,构建者模式创建复杂对象。
- 2.建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
- 3.关注重点不一样,工厂模式只需要创建出来即可,构建者模式还需要关注创建过程。
- 4.工厂模式创建的对象实例都是一样的,构建者如果构建过程不同,创建的对象也不同。
做个简单总结:
- 创建简单实例,工厂模式。
- 创建复杂实例,注重创建过程的,请用构建者模式。
老规矩,看看构建者模式的优缺点和适用场景。
优缺点
-
优点 1.封装性好,构建和表示分离:对外只需要提供构建的接口即可。 2.扩展性好,各个具体的建造者相互独立,有利于系统的解耦。 3.客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险,这相当于对外屏蔽细节,对内自由调整。
-
缺点 1.产品的组成部分必须相同,这限制了其使用范围。 2.如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
适用场景
当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。
所以构建者模式的适用场景主要是:
- 1.相同的方法,不同的执行顺序,产生不同的结果。
- 2.多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
- 3.产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
- 4.初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
代码实现
package main
import "fmt"
/*
业务场景描述:
- 代工厂生产iphone,组装iphone的过程简化为组装、出厂测试、打包
这里涉及到的结构主要分为以下四类:
- 1.产品,iphone手机
- 2.抽象建造者,即抽象工厂
- 3.具体建造者,即具体工厂
- 4.指挥者角色,整合建造者的方法,实现生产产品的流程,最后生产出可直接销售的iphone
*/
// 1.product,为了便于扩展,先写个抽象产品,即接口
type iProduct interface {
introduction()
}
// concrete product
type iphoneProduct struct {
name string
}
func (r *iphoneProduct) introduction() {
fmt.Println("It's iphone.")
}
// 2.abstract factory, or abstract builder, interface
type IPhoneFactory interface {
assemble()
testBeforeSell()
packaging() *iphoneProduct
}
// 3.concrete builder, or factory
type phoneFactory struct {
}
func (r *phoneFactory) assemble() {
fmt.Println("assembling product ...")
}
func (r *phoneFactory) testBeforeSell() {
fmt.Println("testing product ...")
}
func (r *phoneFactory) packaging() *iphoneProduct {
fmt.Println("packaging product ...")
return &iphoneProduct{"iphone 14 pro max"}
}
// 4.director
type director struct {
builder phoneFactory
}
func NewDirector() *director {
return &director{}
}
func (d *director) Set(f phoneFactory) {
d.builder = f
}
func (d *director) Gen() *iphoneProduct {
return d.gen()
}
func (d *director) gen() *iphoneProduct {
d.builder.assemble()
d.builder.testBeforeSell()
return d.builder.packaging()
}
func main() {
d := NewDirector()
d.Set(phoneFactory{})
phone := d.Gen()
fmt.Println(phone)
}
参考: