复杂的对象由多个部分组成,建造者模式吧部件和其组装过程分开,一步步创建复杂的对象。建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式。
建造者模式允许用户通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部具体的构建细节。
#模式结构与分析 UML分析
角色:
Builder:抽象建造者。定义了产品的创建和返回方法ConcreteBuilder:具体建造者 。抽象建造者的具体实现Director:指挥者。隔离客户与生产过程,负责控制产品的生成过程Product:产品角色。负责生产的各类产品假设我们有一个产品类族AbstractProduct这个产品类族有4个核心的模块A、B、C、D。不同的子产品实例如果要实际使用,则必须按照一定的顺序依次构造这4个子模块;但是,不同的子产品的构造顺序可能是不同的。
如果我们还使用工厂模式来构造,那么工厂内部必须要为每个不同的子类来确定模块的建造顺序。而且,可能有部分的子模块构造顺序是相同的,这样会造成代码的冗余,因为相同的构造顺序被写了多次。此时,需要引入建造者模式,把具有相同构造顺序的不同子模块放到一个建造者中进行建造。外层再添加一个Director,这是和用户的交互接口,用户实际使用这个类来获取实际的产品。
代码实例:
#include <iostream> #include <memory> class AbstractProduct { // 抽象产品 public: // 产品有4个不同的顺序,但是使用前要按照特定的顺序构造A、B、C、D模块 virtual void setPartA() = 0; virtual void setPartB() = 0; virtual void setPartC() = 0; virtual void setPartD() = 0; virtual void show() = 0; }; class AbstractBuilder { // 抽象构造者 public: virtual std::shared_ptr<AbstractProduct> build(std::shared_ptr<AbstractProduct> product) = 0; }; class Product1 : public AbstractProduct { // 具体产品1,有自己特有的构造顺序 public: void setPartA() override { std::cout << "Product 1 sets part A\n"; } void setPartB() override { std::cout << "Product 1 sets part B\n"; } void setPartC() override { std::cout << "Product 1 sets part C\n"; } void setPartD() override { std::cout << "Product 1 sets part D\n"; } void show() override { std::cout << "Product1 OK\n"; } }; class Product2 : public AbstractProduct { // 具体产品2,有自己的构造顺序 public: void setPartA() override { std::cout << "Product 2 sets part A\n"; } void setPartB() override { std::cout << "Product 2 sets part B\n"; } void setPartC() override { std::cout << "Product 2 sets part C\n"; } void setPartD() override { std::cout << "Product 2 sets part D\n"; } void show() override { std::cout << "Product2 OK\n"; } }; class Builder1 : public AbstractBuilder { // 建造者1,用于建造和产品1顺序相同产品的建造者 public: std::shared_ptr<AbstractProduct> build(std::shared_ptr<AbstractProduct> product) { product->setPartA(); product->setPartD(); product->setPartC(); product->setPartB(); return product; } }; class Builder2 : public AbstractBuilder { // 建造者2,用于建造和产品2顺序相同产品的建造者 public: std::shared_ptr<AbstractProduct> build(std::shared_ptr<AbstractProduct> product) { product->setPartB(); product->setPartD(); product->setPartA(); product->setPartC(); return product; } }; class Director { // 根据需求返回不同的产品 public: std::shared_ptr<AbstractProduct> getProduct(int id) { switch (id) { case 1: m_spBuilder = std::make_shared<Builder1>(); m_spProduct = m_spBuilder->build(std::make_shared<Product1>()); break; case 2: m_spBuilder = std::make_shared<Builder2>(); m_spProduct = m_spBuilder->build(std::make_shared<Product2>()); break; default: m_spProduct = nullptr; break; } return m_spProduct; } private: std::shared_ptr<AbstractBuilder> m_spBuilder; std::shared_ptr<AbstractProduct> m_spProduct; }; int main() { Director dir; auto p1 = dir.getProduct(1); p1->show(); std::cout << "-----------------\n"; auto p2 = dir.getProduct(2); p2->show(); return 0; }输出:
Product 1 sets part A Product 1 sets part D Product 1 sets part C Product 1 sets part B Product1 OK ----------------- Product 2 sets part B Product 2 sets part D Product 2 sets part A Product 2 sets part C Product2 OK