C++ 建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
一、建造者模式的主要目的和作用
分步骤构建复杂对象:
当创建一个复杂对象需要多个步骤,并且这些步骤的执行顺序可能不同,或者不同的对象可能有不同的构建方式时,建造者模式可以将这些步骤封装在不同的建造者类中,使得对象的构建更加清晰和灵活。
例如,创建一个汽车对象可能需要设置引擎类型、车轮数量、颜色等多个属性。使用建造者模式,可以将这些属性的设置分别放在不同的方法中,然后根据需要组合这些方法来创建不同配置的汽车。
隔离复杂的构建逻辑:
复杂对象的构建过程可能涉及到很多复杂的逻辑和算法,这些逻辑如果直接放在对象的构造函数中,会使得构造函数变得非常复杂和难以理解。建造者模式将这些构建逻辑封装在建造者类中,使得对象的构造函数只负责调用建造者的方法来完成对象的构建,从而提高了代码的可读性和可维护性。
例如,创建一个图形用户界面(GUI)组件可能需要根据不同的平台和用户需求进行复杂的布局和样式设置。使用建造者模式,可以将这些设置逻辑放在专门的建造者类中,使得 GUI 组件的创建更加简单和易于理解。
支持不同的构建方式:
建造者模式允许使用不同的建造者类来创建同一个对象的不同表示。这对于创建具有多种配置选项的对象非常有用,例如不同配置的电脑、不同风格的建筑等。
例如,创建一个电脑对象,可以有不同的建造者类分别用于创建游戏电脑、办公电脑和服务器电脑等不同类型的电脑。每个建造者类可以根据特定的需求设置不同的硬件配置和软件安装。
二、建造者模式的结构和组成部分
产品类(Product):
代表要创建的复杂对象。它包含了创建对象所需的各种属性和方法。
例如,在创建汽车的例子中,汽车类就是产品类,它包含了引擎类型、车轮数量、颜色等属性和启动、行驶等方法。
抽象建造者类(Builder):
定义了创建产品对象的抽象接口,包含了创建产品各个部分的方法。
例如,在创建汽车的例子中,抽象汽车建造者类可以定义设置引擎类型、设置车轮数量、设置颜色等方法。
具体建造者类(ConcreteBuilder):
实现了抽象建造者类的接口,负责具体的产品对象的构建。
例如,在创建汽车的例子中,可以有具体的跑车建造者类、SUV 建造者类等,它们分别实现了抽象汽车建造者类的方法,创建不同类型的汽车。
指挥者类(Director):
负责使用建造者对象来构建产品对象。它可以根据不同的需求调用建造者的方法来创建不同的产品对象。
例如,在创建汽车的例子中,指挥者类可以根据用户的需求选择不同的汽车建造者类,并调用它们的方法来创建相应类型的汽车。
三、建造者模式的示例代码
以下是一个用 C++ 实现的建造者模式的示例代码,以创建一个电脑对象为例:
cpp
#include <iostream>
#include <string>
// 产品类:电脑
class Computer {
private:
std::string cpu;
std::string ram;
std::string graphicsCard;
public:
void setCpu(const std::string& cpu) {
this->cpu = cpu;
}
void setRam(const std::string& ram) {
this->ram = ram;
}
void setGraphicsCard(const std::string& graphicsCard) {
this->graphicsCard = graphicsCard;
}
void show() {
std::cout << "Computer Configuration: CPU = " << cpu << ", RAM = " << ram << ", Graphics Card = " << graphicsCard << std::endl;
}
};
// 抽象建造者类
class ComputerBuilder {
public:
virtual void buildCpu() = 0;
virtual void buildRam() = 0;
virtual void buildGraphicsCard() = 0;
virtual Computer* getComputer() = 0;
};
// 具体建造者类:游戏电脑建造者
class GamingComputerBuilder : public ComputerBuilder {
private:
Computer* computer;
public:
GamingComputerBuilder() {
computer = new Computer();
}
void buildCpu() override {
computer->setCpu("High-performance CPU");
}
void buildRam() override {
computer->setRam("16GB RAM");
}
void buildGraphicsCard() override {
computer->setGraphicsCard("High-end Graphics Card");
}
Computer* getComputer() override {
return computer;
}
};
// 具体建造者类:办公电脑建造者
class OfficeComputerBuilder : public ComputerBuilder {
private:
Computer* computer;
public:
OfficeComputerBuilder() {
computer = new Computer();
}
void buildCpu() override {
computer->setCpu("Moderate-performance CPU");
}
void buildRam() override {
computer->setRam("8GB RAM");
}
void buildGraphicsCard() override {
computer->setGraphicsCard("Integrated Graphics Card");
}
Computer* getComputer() override {
return computer;
}
};
// 指挥者类
class ComputerDirector {
public:
void construct(ComputerBuilder* builder) {
builder->buildCpu();
builder->buildRam();
builder->buildGraphicsCard();
}
};
使用这个建造者模式的示例代码如下:
cpp
int main() {
ComputerDirector director;
GamingComputerBuilder gamingBuilder;
director.construct(&gamingBuilder);
Computer* gamingComputer = gamingBuilder.getComputer();
gamingComputer->show();
OfficeComputerBuilder officeBuilder;
director.construct(&officeBuilder);
Computer* officeComputer = officeBuilder.getComputer();
officeComputer->show();
delete gamingComputer;
delete officeComputer;
return 0;
}
在这个示例中,Computer类是产品类,ComputerBuilder是抽象建造者类,GamingComputerBuilder和OfficeComputerBuilder是具体建造者类,ComputerDirector是指挥者类。通过使用建造者模式,可以根据不同的需求创建不同配置的电脑对象。
四、建造者模式的优缺点
优点:
良好的封装性:
将复杂对象的构建过程封装在建造者类中,使得客户端代码只需要关心如何使用建造者来创建对象,而不需要了解对象的具体构建过程。
灵活性高:可以通过不同的建造者类来创建不同表示的对象,支持不同的构建方式和配置选项。
易于扩展:
如果需要创建新的产品对象或者修改构建过程,可以通过创建新的建造者类或者修改现有的建造者类来实现,而不会影响到客户端代码。
缺点:
增加了代码的复杂性:
建造者模式需要定义多个类,包括产品类、抽象建造者类、具体建造者类和指挥者类,这会增加代码的复杂性和理解难度。
不适合简单对象的创建:
如果创建的对象比较简单,使用建造者模式可能会显得过于复杂。在这种情况下,直接使用构造函数或者工厂方法可能更加简单和直接。
总的来说,C++ 建造者模式是一种非常有用的设计模式,它可以帮助我们更好地管理复杂对象的构建过程,提高代码的可读性、可维护性和灵活性。在实际应用中,我们可以根据具体的需求来选择是否使用建造者模式。