建造者模式(Builder): 将一个复杂对象的构建与它的表示分离,使得同样的构建过程就可以创建不同的表示。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
什么是复杂对象:建造者模式中,复杂对象是指那些包含多个成员属性的对象,这些成员属性称为部件或零件,比如电子邮件包含发件人、收件人、主题、内容、附件等部件。
(1)抽象建造者(Builder)
抽象建造者为创建一个产品Product对象的各个部件指定抽象接口,该接口一般声明两种方法,一类方法用于创建复杂对象的各个部件,另一类方法用于返回复杂对象。
(2)具体建造者(ConcreteBuilder)
具体建造者实现了抽象建造者接口,实现各个部件的构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
(3)产品角色(Product)
产品角色是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。
(4)指挥者(Director)
指挥者负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可调用建造者对象的部件与装配方法,完成发展对象的建造。客户端一般只需要与指挥者交互。
优点:
(1)将产品本身与产品的创建过程解耦,使相同的创建过程可以创建不同的产品对象;
(2)增加新的具体建造者无效修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便。
缺点:
(1)建造者模式所创建的产品一般具有较多的共同点,产品差异过大,则不适合;
对象的创建过程独立于创建该对象的类,在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。
建造者模式比较简单,主要就是将建造过程与具体表示分离,做到了建造过程的抽象,当有新的对象要创建并且建造过程相同,可以继承建造类实现自己的具体表示即可。
KFC 套餐实例,套餐是一个复杂的对象,一个套餐包含主食和饮料等组成部分,不用的套餐 主食和饮料的类型不同,服务员可以根据顾客的需求,一步步完成组成套餐。
通过以上分析,套餐相当于 产品角色,服务员相当于指挥者,不同种类的套餐制作方法称为建造者。
-
- //建造者模式示例代码
- #include
- using namespace std;
- //产品类Meal 为复杂产品对象 有两个属性
- class Meal{
- private:
- std::string food_= "";
- std::string drink_ = "";
- public:
- void setFood(std::string food){
- food_= food;
- }
- std::string getFood(){
- return food_;
- }
- void setDrink(std::string drink){
- drink_= drink;
- }
- std::string getDrink(){
- return drink_;
- }
- };
-
- //抽象建造者
- class MealBuilder
- {
-
- public:
- virtual void buildFood() = 0;
- virtual void buildDrink() = 0;
- virtual Meal* getMeal()= 0;
- // 抽象类构建必须有虚析构函数 以防止内存泄漏
- virtual ~MealBuilder(){
- cout << "~MealBuilder()" << endl;
- }
- };
-
- //具体建造者SubMealBuilderA(A套餐建造者)
- class SubMealBuilderA :public MealBuilder
- {
- public:
- SubMealBuilderA(){
- m_pMeal = new Meal;
- }
- ~SubMealBuilderA(){
- cout << "SubMealBuilderA()" << endl;
- }
- void buildFood()
- {
- m_pMeal->setFood("A drumstick burger");
- cout << "A drumstick burger" << endl;
- }
- void buildDrink()
- {
- m_pMeal->setDrink("A cup of coke");
- cout << "A cup of coke" << endl;
- }
- Meal* getMeal(){
- return m_pMeal;
- }
- private:
- Meal* m_pMeal;
-
- };
-
- //具体建造者SubMealBuilderB(B套餐建造者)
- class SubMealBuilderB :public MealBuilder
- {
- private:
- MealBuilder *pBuilder;
- public:
- SubMealBuilderB(){
- m_pMeal = new Meal;
- }
- ~SubMealBuilderB(){
- cout << "SubMealBuilderB()" << endl;
- }
- void buildFood()
- {
- m_pMeal->setFood("A chicken roll");
- cout << "A chicken roll" << endl;
- }
- void buildDrink()
- {
- m_pMeal->setDrink("a cup of juice");
- cout << "a cup of juice" << endl;
- }
- private:
- Meal* m_pMeal;
- };
-
- //指挥者 WaitDirector
- class WaitDirector
- {
- private:
- MealBuilder *pBuilder;
- public:
- void setMealBuilder(MealBuilder *iBuilder)
- {
- pBuilder = iBuilder;
- }
- Meal* construct()
- {
- pBuilder->buildFood();
- pBuilder->buildDrink();
- return pBuilder->getMeal();
- }
- };
-
- //客户端调用
- int main()
- {
- //确定套餐的种类
- MealBuilder* mb = new SubMealBuilderA();
- //服务员指挥者
- WaitDirector* waiter = new WaitDirector();
- //服务员准备套餐
- waiter->setMealBuilder(mb);
- //客户获得套餐
- waiter->construct();
- Meal* meal = mb->getMeal();
- meal->getFood();
- meal->getDrink();
-
- delete mb;
- mb = nullptr;
- delete waiter;
- mb = waiter;
- delete meal;
- meal = nullptr;
- return 0;
- }
执行结果
A drumstick burger
A cup of coke
SubMealBuilderA()
~MealBuilder()
参考文献: