建造者模式(Builder Pattern)是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。建造者模式通过一步一步地构建最终的复杂对象,使得构建过程更加清晰和灵活。
为了更生动形象地理解建造者模式,我们可以通过一些日常生活中的例子来进行类比。
例子1:制作汉堡
场景描述
假设你在一家快餐店工作,你需要制作各种不同类型的汉堡。每种汉堡的制作过程可能相似,但具体的配料和步骤可能不同。
建造者模式的应用
- 产品:汉堡,它是最终要构建的复杂对象。
- 建造者:汉堡制作人员,它定义了构建汉堡的步骤,如添加面包、添加肉饼、添加蔬菜等。
- 具体建造者:具体的汉堡制作人员,它实现了具体的构建步骤,如制作牛肉汉堡、鸡肉汉堡等。
- 指挥者:店长,它负责指导汉堡制作人员按照特定的顺序构建汉堡。
通过建造者模式,店长可以指导不同的汉堡制作人员制作不同类型的汉堡,而不需要关心具体的制作细节。
类图表示
+----------------+ +----------------+ +----------------+
| Burger | | BurgerBuilder| | BeefBurgerBuilder|
|----------------| |----------------| |----------------|
| + addBun() | | + addBun() | | + addBun() |
| + addPatty() | | + addPatty() | | + addPatty() |
| + addVegetables()| | + addVegetables()| | + addVegetables()|
+----------------+ +----------------+ +----------------+
^ ^ ^
| | |
| | |
+------------------------+ |
| |
| +----------------+ |
| | ChickenBurgerBuilder|
| |----------------| |
| | + addBun() | |
| | + addPatty() | |
| | + addVegetables()| |
| +----------------+ |
| |
+-------------------------------------------------+
代码示例:制作汉堡
#include <iostream>
#include <string>
// 产品:汉堡
class Burger {
public:
void addBun(const std::string& bun) {
std::cout << "Adding " << bun << " bun." << std::endl;
}
void addPatty(const std::string& patty) {
std::cout << "Adding " << patty << " patty." << std::endl;
}
void addVegetables(const std::string& vegetables) {
std::cout << "Adding " << vegetables << " vegetables." << std::endl;
}
};
// 抽象建造者:汉堡制作人员
class BurgerBuilder {
protected:
Burger* burger;
public:
BurgerBuilder() : burger(new Burger()) {}
virtual void addBun() = 0;
virtual void addPatty() = 0;
virtual void addVegetables() = 0;
Burger* getBurger() {
return burger;
}
virtual ~BurgerBuilder() {
delete burger;
}
};
// 具体建造者:牛肉汉堡制作人员
class BeefBurgerBuilder : public BurgerBuilder {
public:
void addBun() override {
burger->addBun("sesame");
}
void addPatty() override {
burger->addPatty("beef");
}
void addVegetables() override {
burger->addVegetables("lettuce and tomato");
}
};
// 具体建造者:鸡肉汉堡制作人员
class ChickenBurgerBuilder : public BurgerBuilder {
public:
void addBun() override {
burger->addBun("whole wheat");
}
void addPatty() override {
burger->addPatty("chicken");
}
void addVegetables() override {
burger->addVegetables("lettuce and cucumber");
}
};
// 指挥者:店长
class Director {
public:
void construct(BurgerBuilder* builder) {
builder->addBun();
builder->addPatty();
好的,我们继续完成建造者模式的代码示例。
### 代码示例:制作汉堡(续)
```cpp
builder->addVegetables();
}
};
// 客户端代码
int main() {
Director director;
// 制作牛肉汉堡
BurgerBuilder* beefBurgerBuilder = new BeefBurgerBuilder();
director.construct(beefBurgerBuilder);
Burger* beefBurger = beefBurgerBuilder->getBurger();
delete beefBurgerBuilder;
std::cout << std::endl;
// 制作鸡肉汉堡
BurgerBuilder* chickenBurgerBuilder = new ChickenBurgerBuilder();
director.construct(chickenBurgerBuilder);
Burger* chickenBurger = chickenBurgerBuilder->getBurger();
delete chickenBurgerBuilder;
return 0;
}
在这个示例中,Burger
类是产品,它表示最终要构建的复杂对象。BurgerBuilder
类是抽象建造者,它定义了构建汉堡的步骤。BeefBurgerBuilder
和 ChickenBurgerBuilder
类是具体建造者,它们实现了具体的构建步骤。Director
类是指挥者,它负责指导建造者按照特定的顺序构建汉堡。
通过建造者模式,指挥者可以指导不同的建造者制作不同类型的汉堡,而不需要关心具体的制作细节。
例子2:建造房子
场景描述
假设你是一名建筑师,你需要建造各种不同类型的房子。每种房子的建造过程可能相似,但具体的步骤和材料可能不同。
建造者模式的应用
- 产品:房子,它是最终要构建的复杂对象。
- 建造者:房子建造者,它定义了构建房子的步骤,如建造地基、建造墙壁、建造屋顶等。
- 具体建造者:具体的房子建造者,它实现了具体的构建步骤,如建造木屋、建造砖房等。
- 指挥者:建筑师,它负责指导房子建造者按照特定的顺序构建房子。
通过建造者模式,建筑师可以指导不同的房子建造者建造不同类型的房子,而不需要关心具体的建造细节。
类图表示
+----------------+ +----------------+ +----------------+
| House | | HouseBuilder | | WoodHouseBuilder|
|----------------| |----------------| |----------------|
| + buildFoundation()| | + buildFoundation()| | + buildFoundation()|
| + buildWalls() | | + buildWalls() | | + buildWalls() |
| + buildRoof() | | + buildRoof() | | + buildRoof() |
+----------------+ +----------------+ +----------------+
^ ^ ^
| | |
| | |
+------------------------+ |
| |
| +----------------+ |
| | BrickHouseBuilder|
| |----------------| |
| | + buildFoundation()| |
| | + buildWalls() | |
| | + buildRoof() | |
| +----------------+ |
| |
+-------------------------------------------------+
代码示例:建造房子
#include <iostream>
#include <string>
// 产品:房子
class House {
public:
void buildFoundation(const std::string& foundation) {
std::cout << "Building " << foundation << " foundation." << std::endl;
}
void buildWalls(const std::string& walls) {
std::cout << "Building " << walls << " walls." << std::endl;
}
void buildRoof(const std::string& roof) {
std::cout << "Building " << roof << " roof." << std::endl;
}
};
// 抽象建造者:房子建造者
class HouseBuilder {
protected:
House* house;
public:
HouseBuilder() : house(new House()) {}
virtual void buildFoundation() = 0;
virtual void buildWalls() = 0;
virtual void buildRoof() = 0;
House* getHouse() {
return house;
}
virtual ~HouseBuilder() {
delete house;
}
};
// 具体建造者:木屋建造者
class WoodHouseBuilder : public HouseBuilder {
public:
好的,我们继续完成建造房子的代码示例。
### 代码示例:建造房子(续)
```cpp
void buildFoundation() override {
house->buildFoundation("wooden");
}
void buildWalls() override {
house->buildWalls("wooden");
}
void buildRoof() override {
house->buildRoof("wooden");
}
};
// 具体建造者:砖房建造者
class BrickHouseBuilder : public HouseBuilder {
public:
void buildFoundation() override {
house->buildFoundation("concrete");
}
void buildWalls() override {
house->buildWalls("brick");
}
void buildRoof() override {
house->buildRoof("tile");
}
};
// 指挥者:建筑师
class Architect {
public:
void construct(HouseBuilder* builder) {
builder->buildFoundation();
builder->buildWalls();
builder->buildRoof();
}
};
// 客户端代码
int main() {
Architect architect;
// 建造木屋
HouseBuilder* woodHouseBuilder = new WoodHouseBuilder();
architect.construct(woodHouseBuilder);
House* woodHouse = woodHouseBuilder->getHouse();
delete woodHouseBuilder;
std::cout << std::endl;
// 建造砖房
HouseBuilder* brickHouseBuilder = new BrickHouseBuilder();
architect.construct(brickHouseBuilder);
House* brickHouse = brickHouseBuilder->getHouse();
delete brickHouseBuilder;
return 0;
}
在这个示例中,House
类是产品,它表示最终要构建的复杂对象。HouseBuilder
类是抽象建造者,它定义了构建房子的步骤。WoodHouseBuilder
和 BrickHouseBuilder
类是具体建造者,它们实现了具体的构建步骤。Architect
类是指挥者,它负责指导建造者按照特定的顺序构建房子。
通过建造者模式,建筑师可以指导不同的建造者建造不同类型的房子,而不需要关心具体的建造细节。
总结
建造者模式的核心思想是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。通过建造者模式,可以一步一步地构建最终的复杂对象,使得构建过程更加清晰和灵活。
建造者模式的优点
- 分离构建过程和表示:建造者模式将构建过程与表示分离,使得同样的构建过程可以创建不同的表示。
- 更好的控制构建过程:通过建造者模式,可以一步一步地构建复杂对象,更好地控制构建过程。
- 提高代码的可读性和可维护性:建造者模式使得构建过程更加清晰,提高了代码的可读性和可维护性。
建造者模式的缺点
- 增加系统的复杂性:建造者模式引入了更多的类和接口,增加了系统的复杂性。
- 需要理解构建过程和表示的分离:开发人员需要理解构建过程和表示的分离,并合理地设计系统结构。
通过上述示例,我们可以更生动形象地理解建造者模式:
- 制作汉堡:将汉堡的制作过程与具体的配料分离,使得同样的制作过程可以制作不同类型的汉堡。
- 建造房子:将房子的建造过程与具体的材料分离,使得同样的建造过程可以建造不同类型的房子。
建造者模式在实际开发中广泛应用,特别是在需要灵活构建和维护复杂对象的系统中。通过合理地使用建造者模式,可以提高系统的可扩展性和可维护性。