建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。该模式允许你逐步构建复杂对象,同时将构建步骤的具体实现封装起来,客户端只需要指定要构建的对象类型,而不需要关心对象的具体构建细节。
代码复杂度增加:引入多个角色和类,使代码复杂、类数量增多,简单对象创建用此模式会繁琐。
若建造过程简单,可考虑将指挥者和抽象建造者的功能合并。比如小型软件项目中,对象构建步骤少且固定,就无需单独的指挥者类,让具体建造者直接负责控制构建顺序,减少类的数量和交互复杂度。
适用范围有限:主要适用于复杂对象,对简单对象或无明显构建步骤和顺序要求的对象不适用。
增加系统开销:创建多个类和对象会增加内存占用和创建时间,影响对性能要求高的系统。
为方便理解,下面我们以建造电脑为例,使用建造者模式来实现。电脑是我们要创建的复杂对象,包括 CPU、内存、硬盘等组件。
为避免手动管理内存,减少内存泄露风险,C++实现使用智能指针管理对象
#include
#include
#include
// 产品:电脑
class Computer {
public:
void setCPU(const std::string& cpu) {
m_cpu = cpu;
}
void setMemory(const std::string& memory) {
m_memory = memory;
}
void setHardDisk(const std::string& hardDisk) {
m_hardDisk = hardDisk;
}
void showInfo() const {
std::cout << "CPU: " << m_cpu << std::endl;
std::cout << "Memory: " << m_memory << std::endl;
std::cout << "Hard Disk: " << m_hardDisk << std::endl;
}
private:
std::string m_cpu;
std::string m_memory;
std::string m_hardDisk;
};
// 抽象建造者
class ComputerBuilder {
public:
virtual ~ComputerBuilder() = default;
virtual void buildCPU() = 0;
virtual void buildMemory() = 0;
virtual void buildHardDisk() = 0;
virtual std::unique_ptr getComputer() = 0;
};
// 具体建造者:高端电脑建造者
class HighEndComputerBuilder : public ComputerBuilder {
public:
HighEndComputerBuilder() {
m_computer = std::make_unique();
}
void buildCPU() override {
m_computer->setCPU("Intel Core i9");
}
void buildMemory() override {
m_computer->setMemory("64GB DDR5");
}
void buildHardDisk() override {
m_computer->setHardDisk("2TB SSD");
}
std::unique_ptr getComputer() override {
return std::move(m_computer);
}
private:
std::unique_ptr m_computer;
};
// 具体建造者:低端电脑建造者
class LowEndComputerBuilder : public ComputerBuilder {
public:
LowEndComputerBuilder() {
m_computer = std::make_unique();
}
void buildCPU() override {
m_computer->setCPU("Intel Core i3");
}
void buildMemory() override {
m_computer->setMemory("8GB DDR4");
}
void buildHardDisk() override {
m_computer->setHardDisk("500GB HDD");
}
std::unique_ptr getComputer() override {
return std::move(m_computer);
}
private:
std::unique_ptr m_computer;
};
// 指挥者
class ComputerDirector {
public:
explicit ComputerDirector(std::unique_ptr builder)
: m_builder(std::move(builder)) {}
std::unique_ptr constructComputer() {
m_builder->buildCPU();
m_builder->buildMemory();
m_builder->buildHardDisk();
return m_builder->getComputer();
}
private:
std::unique_ptr m_builder;
};
int main() {
// 建造高端电脑
auto highEndBuilder = std::make_unique();
ComputerDirector highEndDirector(std::move(highEndBuilder));
auto highEndComputer = highEndDirector.constructComputer();
std::cout << "High End Computer Info:" << std::endl;
highEndComputer->showInfo();
// 建造低端电脑
auto lowEndBuilder = std::make_unique();
ComputerDirector lowEndDirector(std::move(lowEndBuilder));
auto lowEndComputer = lowEndDirector.constructComputer();
std::cout << "\nLow End Computer Info:" << std::endl;
lowEndComputer->showInfo();
return 0;
}
// 产品:电脑
class Computer {
private String cpu;
private String memory;
private String hardDisk;
public void setCPU(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public void showInfo() {
System.out.println("CPU: " + cpu);
System.out.println("Memory: " + memory);
System.out.println("Hard Disk: " + hardDisk);
}
}
// 抽象建造者
interface ComputerBuilder {
void buildCPU();
void buildMemory();
void buildHardDisk();
Computer getComputer();
}
// 具体建造者:高端电脑建造者
class HighEndComputerBuilder implements ComputerBuilder {
private Computer computer;
public HighEndComputerBuilder() {
this.computer = new Computer();
}
@Override
public void buildCPU() {
computer.setCPU("Intel Core i9");
}
@Override
public void buildMemory() {
computer.setMemory("64GB DDR5");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("2TB SSD");
}
@Override
public Computer getComputer() {
return this.computer;
}
}
// 具体建造者:低端电脑建造者
class LowEndComputerBuilder implements ComputerBuilder {
private Computer computer;
public LowEndComputerBuilder() {
this.computer = new Computer();
}
@Override
public void buildCPU() {
computer.setCPU("Intel Core i3");
}
@Override
public void buildMemory() {
computer.setMemory("8GB DDR4");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("500GB HDD");
}
@Override
public Computer getComputer() {
return this.computer;
}
}
// 指挥者
class ComputerDirector {
private ComputerBuilder builder;
public ComputerDirector(ComputerBuilder builder) {
this.builder = builder;
}
public Computer constructComputer() {
builder.buildCPU();
builder.buildMemory();
builder.buildHardDisk();
return builder.getComputer();
}
}
// 主类
public class BuilderPatternDemo {
public static void main(String[] args) {
// 建造高端电脑
ComputerBuilder highEndBuilder = new HighEndComputerBuilder();
ComputerDirector highEndDirector = new ComputerDirector(highEndBuilder);
Computer highEndComputer = highEndDirector.constructComputer();
System.out.println("High End Computer Info:");
highEndComputer.showInfo();
// 建造低端电脑
ComputerBuilder lowEndBuilder = new LowEndComputerBuilder();
ComputerDirector lowEndDirector = new ComputerDirector(lowEndBuilder);
Computer lowEndComputer = lowEndDirector.constructComputer();
System.out.println("\nLow End Computer Info:");
lowEndComputer.showInfo();
}
}
基于上述代码,对建造者模式的相关“角色”加以解释说明。
Computer
类就是产品,它包含了 CPU、内存、硬盘等多个组件。ComputerBuilder
类,它定义了buildCPU
、buildMemory
、buildHardDisk
等方法,用于构建电脑的各个组件。HighEndComputerBuilder
和LowEndComputerBuilder
类,分别实现了构建高端电脑和低端电脑的具体逻辑。ComputerDirector
类,它调用具体建造者的buildCPU
、buildMemory
、buildHardDisk
方法,按照一定的顺序构建电脑。HighEndComputerBuilder
,要创建低端电脑就选择LowEndComputerBuilder
。ComputerDirector highEndDirector(&highEndBuilder);
。highEndDirector.constructComputer();
方法会依次调用highEndBuilder
的buildCPU
、buildMemory
、buildHardDisk
方法。Computer highEndComputer = highEndDirector.getComputer();
。比较维度 | 工厂模式 | 建造者模式 |
相同点 | 都属于创建型设计模式,主要目的都是封装对象的创建过程,将对象的创建和使用分离,提高代码的可维护性和可扩展性,让客户端无需关注对象创建的具体细节,只需调用相应的接口获取对象即可。 | |
不同点 | ||
目的侧重点 | 重点在于提供一种统一的方式来创建不同类型的对象,更强调对象创建的结果,关注如何根据不同的条件创建出不同类型的对象实例。 | 强调对象的构建过程,注重将一个复杂对象的构建过程和表示分离,允许按步骤构建对象,能灵活控制对象的构建细节。 |
复杂度与构建步骤 | 创建过程相对简单,通常是根据传入的参数或条件一次性创建出完整的对象,不涉及多个复杂的构建步骤。 | 适用于创建复杂对象,对象的构建过程由多个步骤组成,每个步骤可能有不同的操作和配置,通过逐步调用不同的构建方法来完成对象的创建。 |
代码结构与角色 | 一般包含工厂类和产品类。工厂类负责对象的创建逻辑,产品类是工厂创建的目标对象。 | 包含产品、抽象建造者、具体建造者和指挥者四个主要角色。抽象建造者定义构建步骤,具体建造者实现构建逻辑,指挥者控制构建顺序。 |
灵活性 | 创建逻辑相对固定,一旦确定创建规则,较难在创建过程中动态调整对象的属性和配置。 | 灵活性高,可以根据不同需求灵活调整对象的构建过程,通过不同的具体建造者和指挥者组合创建不同表示和配置的对象。 |
应用方向 | ||
应用场景 | - 创建对象的逻辑相对简单,只需要根据不同条件返回不同类型的对象时使用,如创建不同类型的数据库连接对象。 - 需要创建多种相关但又有区别的对象时,例如不同风格的按钮、不同格式的文档解析器等。 | - 创建复杂对象,且对象的构建过程有明显的步骤划分,如构建电脑、汽车等产品。 - 需要根据不同的配置或参数组合来创建对象时,如创建不同套餐的旅游行程、不同规格的房屋等。 |
示例 | 文件读取器工厂可以根据文件类型(如文本文件、CSV 文件、JSON 文件)创建不同的读取器对象。 | 游戏角色创建系统,可逐步设置角色的外貌、技能、装备等属性来创建不同类型的角色。 |
建造者模式将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。上述与工厂模式的对比中已经简要陈述了应用场景,此处做更详细地说明。
当需要创建的对象是由多个部分组成,且各个部分的构建过程较为复杂,同时构建顺序也可能不同时,建造者模式非常适用。它可以将复杂对象的构建过程分解为多个简单的步骤,每个步骤由具体建造者负责实现,从而提高代码的可维护性和可扩展性。
如果一个对象有多种不同的配置组合方式,并且这些配置组合的创建过程较为复杂,使用建造者模式可以方便地管理和创建这些不同的配置。
当对象的构建过程有严格的顺序要求时,建造者模式可以通过指挥者类来控制构建步骤的执行顺序,确保对象按照正确的顺序进行构建。