一、什么是建造者模式
建造者模式是一种创建型设计模式,它允许你逐步构造复杂对象。
该模式将对象的构造过程与其表示分离,使得同样的构造过程可以创建不同的表示。
主要解决的问题是在创建一个复杂对象时,需要多个步骤和多个部件,并且这些步骤和部件的组合方式可能会产生不同的结果。
二、为什么需要建造者模式
- 对象的构建过程非常复杂时,需要多个步骤和不同的部件来完成时,可以使用建造者模式。通过将构建过程分解为多个步骤,每个步骤负责构建一个部件,最终组装成一个完整的对象。
- 当对象具有多个变化点时,如果需要根据不同的需求创建不同的对象时,可以使用建造者模式。通过定义不同的具体建造者,每个建造者负责创建不同的对象表示,可以灵活地组合不同的部件来构建不同的对象。
- 将复杂对象的构建过程与其表示分离时,使得构建过程更加灵活,可以根据需要动态改变构建过程,而不影响最终的表示。
- 当需要隐藏复杂对象的创建细节时,使得使用者只需要关心最终的构建结果,而不需要知道具体的构建过程。可以通过不同的构建者来创建不同的表示,从而实现了构建过程的复用和扩展。可以避免构建过程中的重复代码,提高代码的复用性和可维护性。
总之,建造者模式可以帮助我们更加灵活、可扩展地构建复杂对象,提高代码的可读性和可维护性。
三、举例说明建造者模式的应用场景
构建电脑对象
- 假设我们要创建一个电脑对象,它包含CPU、内存、硬盘等部件。
- 如果我们直接在代码中创建电脑对象,那么构建过程将会非常复杂,而且如果需要创建不同配置的电脑,代码将会变得非常冗长。
- 使用建造者模式,我们可以定义一个电脑建造者,它负责构建电脑对象的各个部件。
- 我们可以定义不同的具体建造者,每个建造者负责创建不同配置的电脑。
- 通过指定不同的建造者,我们可以灵活地构建不同配置的电脑对象,而不需要关心具体的构建过程。
- 这样,我们可以将复杂的构建过程与表示分离,使得代码更加清晰、可维护,并且可以方便地扩展和修改不同的部件和配置。
构建汽车对象
- 在汽车制造过程中,汽车由多个部件组成,例如发动机、底盘、车身、轮胎等。
- 每个部件都有不同的属性和配置选项。建造者模式可以将汽车的构建过程与表示分离,使得同样的构建过程可以创建不同配置的汽车。
- 先创建一个抽象的汽车建造者接口,定义了构建汽车各个部件的方法。
- 然后有具体的汽车建造者类实现这个接口,负责具体的部件构建。
- 最后有一个指挥者类,负责按照一定的顺序调用汽车建造者的方法来构建汽车。
建造房屋对象
- 假设你要建造一座房子,你可以使用建造者模式来逐步构建房子的不同部分,例如地基、墙壁、屋顶等。
- 每个部分都有自己的构造过程和表示方式。建造者模式允许你根据需要选择不同的部分组合来构建不同类型的房子。
- 你可以使用建造者模式来构建一座别墅和一座公寓。别墅可能有更大的地基、更多的房间和更豪华的装饰,而公寓可能有较小的地基、较少的房间和简单的装饰。
- 通过使用建造者模式,你可以根据需要选择不同的部分组合来构建不同类型的房子,而不需要修改构造过程。
- 这种方式使得构造过程更加灵活,易于扩展和维护。同时,它还可以隐藏构造细节,使客户端代码更加简洁和易于理解。
四、建造者模式的通用代码实现
// 产品类
class Product
{
public:
void Add(string);
void Show();
protected:
string parts[];
};
// 创建产品的一个部分
void Product::Add(string part)
{
int size=ArraySize(parts);
ArrayResize(parts,size+1);
parts[size]=part;
Print("添加的产品的 ", part, "给自己.");
}
// 产品的显示
void Product::Show(void)
{
Print("该产品展示了它的所有部件.");
int total=ArraySize(parts);
for(int i=0; i<total; i++)
Print(parts[i]);
}
// 创建者接口
interface Builder
{
// 创建部分A
void BuildPartA();
// 创建部分B
void BuildPartB();
// 创建部分C
void BuildPartC();
// 获取产品
Product* GetResult();
};
// 指挥者
class Director
{
public:
void Construct();
Director(Builder*);
~Director();
protected:
Builder* builder;
};
void Director::Director(Builder *b)
{
builder=b;
Print("指挥者创造并接受建设者", b);
}
void Director::~Director(void)
{
delete builder;
}
// 创建函数,分步骤创建
void Director::Construct(void)
{
Print("指挥开始构建");
Print("指挥者请求建造者按要求建造产品零件");
builder.BuildPartA();
builder.BuildPartB();
builder.BuildPartC();
Print("指挥建造者零件建造了这个产品");
}
// 具体建造者,不同的建造者创建不同的产品
class ConcreteBuilder : public Builder
{
public:
void BuildPartA();
void BuildPartB();
void BuildPartC();
Product* GetResult();
protected:
Product product;
};
void ConcreteBuilder::BuildPartA(void)
{
Print("部件A 添加到产品自身");
product.Add("部件 A");
Print("建设者制作了A部分并将其添加到产品中");
}
void ConcreteBuilder::BuildPartB(void)
{
Print("部件B 添加到产品自身");
product.Add("部件 B");
Print("建设者制作了B部分并将其添加到产品中");
}
void ConcreteBuilder::BuildPartC(void)
{
Print("部件C 添加到产品自身");
product.Add("部件 C");
Print("建设者制作了C部分并将其添加到产品中");
}
Product* ConcreteBuilder::GetResult(void)
{
Print("返回构建好的产品本身");
return &product;
}
class Client
{
public:
string Output();
void Run();
};
string Client::Output() {return __FUNCTION__;}
void Client::Run()
{
Print("客户要求创建一个新的建造者");
Builder* builder=new ConcreteBuilder;
Print("客户要求创建一名指挥者,并将建造者交给他");
Director director(builder);
Print("客户要求指挥者指挥建造");
director.Construct();
Print("客户端请求建造者返回产品结果");
Product* product=builder.GetResult();
Print("客户要求产品描述自己");
product.Show();
}