目录
一、什么是建造者模式
二、建造者模式的结构
三、建造者模式的代码实现
四、建造者模式的优缺点
五、建造者模式的应用场景
六、对比
七、总结
一、什么是建造者模式
建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是将一个复杂对象的构建过程与它的实现表示分离,使得同样的构建过程可以创建不同的表示,属于创建型模式。使用创建者模式对于用户而言只需要制定需要建造的类就可以获得对象,建造过程及细节不需要了解。
建造者模式适用于创建对象需要很多步骤,但是步骤的顺序不一定固定。如果一个对象有非常复杂的内部结构,可以将复杂对象的创建和使用进行分离。
二、建造者模式的结构
角色 | 含义 |
---|---|
产品角色 | 它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件 |
抽象建造者 | 它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 |
具体建造者 | 实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。可以有不同的具体建造者 |
指挥者 | 它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息 |
三、建造者模式的代码实现
python实现
from abc import ABCMeta, abstractmethod
class Player(object):
def __init__(self, face=None, leg=None):
self.face = face
self.leg = leg
def __str__(self):
return f'{self.face}--{self.leg}'
# 抽象建造者
class BaseBuilder(metaclass=ABCMeta):
@abstractmethod
def build_face(self):
pass
@abstractmethod
def build_leg(self):
pass
class BeautifulBuilder(BaseBuilder):
def __init__(self):
self.player = Player()
def build_face(self):
self.player.face = '美女的脸'
def build_leg(self):
self.player.leg = '美女的腿'
class MonsterBuilder(BaseBuilder):
def __init__(self):
self.player = Player()
def build_leg(self):
self.player.leg = '怪兽的腿'
def build_face(self):
self.player.face = '怪兽的脸'
class PlayerDirector(object):
def build_player(self, builder):
builder.build_face()
builder.build_leg()
return builder.player
if __name__ == '__main__':
builder = MonsterBuilder()
director = PlayerDirector()
p = director.build_player(builder)
print(p)
golang实现
type Person struct {
name, sex, address string
age int
}
func (p *Person) PrintInfo() {
fmt.Printf("姓名: %s, 年龄: %d, 性别: %s, 住址: %s\n", p.name, p.age, p.sex, p.address)
}
type PersonBuilder struct {
person *Person
}
func NewPersonBuilder() *PersonBuilder {
return &PersonBuilder{person: &Person{}}
}
func (p *PersonBuilder) Name(name string) *PersonBuilder {
p.person.name = name
return p
}
func (p *PersonBuilder) Sex(sex string) *PersonBuilder {
p.person.sex = sex
return p
}
func (p *PersonBuilder) Address(address string) *PersonBuilder {
p.person.address = address
return p
}
func (p *PersonBuilder) Age(age int) *PersonBuilder {
p.person.age = age
return p
}
func (p *PersonBuilder) Build() *Person {
return p.person
}
func main() {
p := NewPersonBuilder().
Name("张三").
Age(18).
Sex("男").
Address("上海").
Build()
p.PrintInfo()
}
四、建造者模式的优缺点
优点
客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
每一个具体建造者都独立,因此可以方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
- 可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
- 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭”。
缺点
- 当建造者过多时,会产生很多类,难以维护。
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,若产品之间的差异性很大,则不适合使用该模式,因此其使用范围受到一定限制。
- 若产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
五、建造者模式的应用场景
建造者模式主要适用于以下应用场景:
- 相同的方法,不同的执行顺序,产生不同的结果。
- 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
- 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
- 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
六、对比
工厂模式和建造者模式的对比
建造者模式唯一区别于工厂模式的是是否是复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式。
当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。
- 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
- 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
- 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
- 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。
七、总结
建造者模式的使用场合是当创建复杂对象时,把创建对象成员和装配方法分离出来,放在建造者类中去实现,用户使用该复杂对象时,不用理会它的创建和装配过程,只关心它的表示形式。