Builder 模式是一种创建对象的设计模式,它将对象的构建过程与其表示分离,允许按照步骤构建复杂对象。它提供了一种可读性强、灵活性高的方式来构建对象。
使用 Builder 模式时,通常会有以下几个核心角色:
-
产品(Product):表示正在构建的复杂对象。它通常具有多个属性和方法。
-
抽象建造者(Abstract Builder):定义了构造产品所需的步骤和方法。它是一个接口或抽象类,其中包含设置产品属性的方法。
-
具体建造者(Concrete Builder):实现了抽象建造者接口,负责实际构建产品。它实现了抽象建造者中定义的方法,并提供了具体的实现细节。
-
指导者(Director):负责使用构建器来构建产品。它定义了一个构建方法,该方法按照特定的顺序调用构造器的方法,从而构建出一个完整的产品。
Builder 模式的使用流程如下:
-
定义一个产品类,其中包含需要构建的复杂对象的属性和方法。
-
创建一个抽象建造者接口或抽象类,其中定义了构建产品所需的方法。
-
创建一个或多个具体建造者类,它们实现了抽象建造者接口或抽象类,并提供了具体的构建逻辑。
-
创建一个指导者类,它接收具体的建造者对象,并定义了构建产品的方法,按照特定的顺序调用建造者的方法。
-
在客户端代码中,通过实例化具体建造者和指导者对象,并调用指导者的构建方法,即可构建出一个完整的产品。
Builder 模式的使用场景和优点如下:
-
创建复杂对象:当需要创建具有多个组成部分的复杂对象时,可以使用 Builder 模式。它允许你按照步骤构建对象,而不是一次性调用一个复杂的构造函数。
-
隔离复杂对象的构建和表示:Builder 模式将构建过程与表示分离,使得构建过程更加灵活。你可以根据需要更改产品的构建过程,而无需修改客户端代码。
-
支持不同的构建方式:Builder 模式支持通过不同的具体建造者实现不同的构建方式。你可以根据需要创建不同的具体建造者,从而构建出不同的产品变体。
-
提高代码可读性:Builder 模式使用了具有描述性名称的方法来设置属性,使得代码更加可读和易于理解。
-
避免重叠构造函数:Builder 模式避免了过多的构造函数重载,使得代码更加简洁。相比于使用多个构造函数,它提供了一种更好的方式来创建对象。
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。比如一个餐厅菜品种类有限,但是可以有很多组合。
建造者模式在创建复杂对象时非常有用,特别是当对象的构建过程涉及多个步骤或参数时。它可以提供更好的灵活性和可维护性,同时使得代码更加清晰可读。
> 注意事项: 与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
示例代码如下
#include <iostream>
#include <string>
// 产品类
class Product
{
private:
int price;
std::string origin;
public:
void setPrice(int _price)
{
this->price = _price;
}
void setOrigin(const std::string &_origin)
{
this->origin = _origin;
}
void descriProduct()
{
std::cout << "price: $" << this->price << std::endl;
std::cout << "origin: " << this->origin << std::endl;
}
};
// 抽象创建者
class AbstratBuilder
{
public:
virtual void buildProductPrice(int _price) = 0;
virtual void buildProductOrigin(const std::string &_origin) = 0;
virtual Product &getProduct() = 0;
};
// 具体创建者
class Builder : public AbstratBuilder
{
private:
Product *product;
public:
Builder()
{
this->product = new Product();
}
void buildProductOrigin(const std::string &_origin)
{
product->setOrigin(_origin);
}
void buildProductPrice(int _price)
{
product->setPrice(_price);
}
Product &getProduct()
{
return *product;
}
};
// 指导者
class Diretor
{
public:
void Construct(Builder &builder)
{
builder.buildProductPrice(100);
builder.buildProductOrigin("China");
builder.getProduct().descriProduct();
}
};
int main(int argc, char const *argv[])
{
Builder *builder = new Builder();
Diretor director;
director.Construct(*builder);
return 0;
}
Product
,其中包含了产品的属性和描述产品的方法。然后,我们定义了一个抽象创建者类 AbstractBuilder
,其中定义了构建产品的纯虚函数,并提供了获取产品的方法。
接下来,我们创建了具体创建者类 Builder
,它继承了抽象创建者类,并实现了构建产品的方法。在具体创建者中,我们创建了一个产品对象,并在构建方法中设置了产品的属性。最后,我们定义了一个指导者类 Director
,它接收一个具体创建者对象,并调用创建者的方法来构建产品。
在客户端代码中,我们实例化了具体创建者对象 Builder
,然后将其传递给指导者 Director
的 Construct
方法。指导者根据特定的顺序调用创建者的方法来构建产品,并通过创建者的 getProduct
方法获取构建好的产品,并调用产品的描述方法。
这个示例将对象的构建过程与表示分离,提供了一种灵活且可读性强的方式来构建复杂对象。