生成器(Builder)

生成器(Builder)

一、简介

  1. 意图: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

  2. 结构:

    其中:

    • Builder为创建一个Product对象的各个部件指定抽象接口。

    • ConcreteBuilder实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,提供一个检索产品的接口。

    • Director构造一个使用Builder接口的对象。

    • Product表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组件的类,包括将这些组件装配成最终的接口

  3. 适用性

    Builder模式适用于:

    • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
    • 当构造过程必须允许被构造的对象有不同的表示时。

二、示例

  1. 2017上半年下午
    某快餐厅主要制作并出售儿童套餐,一般包括主餐(各类披萨)、饮料和玩具,其餐品种类可能不同,但其制作过程相同。前台服务员(Waiter)调度厨师制作套餐。现采用生成器Builder)模式实现制作过程。

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Pizza
    {
    private:
    	string parts;
    public:
    	void setParts(string parts) { this->parts = parts; }
    	string getParts() { return parts; }
    };
    
    class PizzaBuilder
    {
    protected:
    	Pizza* pizza;
    public:
    	Pizza* getPizza() { return pizza; }
    	void createNewPizza() { pizza = new Pizza(); }
    	virtual void buildParts() = 0; // 1
    };
    
    class HawaiianPizzaBuilder : public PizzaBuilder
    {
    public:
    	void buildParts() { pizza->setParts("cross + mild + ham&pineapple"); }
    };
    
    class SpicyPizzaBuilder : public PizzaBuilder
    {
    public:
    	void buildParts() { pizza->setParts("pan baked + hot + pepperoni&salami"); }
    };
    
    class Waiter
    {
    private:
    	PizzaBuilder* pizzaBuilder;
    public:
    	void setPizzaBuilder(PizzaBuilder * pizzaBuilder){/*设置构建器*/
    		this->pizzaBuilder = pizzaBuilder;// 2
    	}
    	Pizza* getPizza() { return pizzaBuilder->getPizza(); }
    	void construct(){
    		pizzaBuilder->createNewPizza();
    		pizzaBuilder->buildParts();// 3
    	}
    };
    
    int main()
    {
    	Waiter* waiter = new Waiter();
    	PizzaBuilder* hawaiian_pizzabuilder = new HawaiianPizzaBuilder();
    	// hawaiian_pizzabuilder->buildParts(); // 子生成器不需要显示调用,direactor->construct()中调用
    	waiter->setPizzaBuilder(hawaiian_pizzabuilder); // 4
    	waiter->construct(); // 5
    	cout << "pizza" << waiter->getPizza()->getParts() << endl;
    }
    
  2. 2018年上半年下午

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Product
    {
    private:
    	string partA, partB;
    public:
    	Product() {}
    	void setPartA(const string& s) { partA = s; }
    	void setPartB(const string& s) { partB = s; }
    	// 其余代码省略
    };
    
    class Builder
    {
    public:
    	virtual void buildPartA() = 0; // 1
    	virtual void buildPartB() = 0;
    	virtual Product* getResult() = 0; // 2
    };
    
    class ConcreteBuilder1 : public Builder
    {
    private:
    	Product* product;
    public:
    	ConcreteBuilder1() { product = new Product(); }
    	void buildPartA() { product->setPartA("Component A"); } // 3
    	void buildPartB() { product->setPartB("Component B"); } // 4
    	Product* getResult() { return product; }
    	// 其余代码省略
    };
    
    class ConcreteBuilder2 : public Builder
    {
    	// 其余代码省略
    };
    
    class Director
    {
    private:
    	Builder* builder;
    public:
    	Director(Builder* pBuilder) { builder = pBuilder; }
    	void construct()
    	{
    		builder->buildPartA(); // 5
    		// 其余代码省略
    	}
    };
    
    int main()
    {
    	Director* director1 = new Director(new ConcreteBuilder1());
    	director1->construct();
    	delete director1;
    
    	return 0;
    }
    
    
posted @ 2022-12-04 14:16  某科学的撒把豆子  阅读(272)  评论(0)    收藏  举报