构建器/建造者/构建者模式(C++)

定义

将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。

应用场景

  • 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
  • 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法"不随着需求改变而改变?

结构

在这里插入图片描述

代码示例

//Builder.h
/****************************************************/
#ifndef BUILDER_H
#define BUILDER_H
#include<iostream>
#include<vector>
using namespace std;

//创建一个表示食物包装的抽象基类接口
class package {
    
    
	public:
		package() {
    
    };
		virtual ~package() {
    
    };
		virtual string pack_way(void)=0;
};

//创建一个纸包装的类继承包装抽象基类
class Wrapper :public package {
    
    
	public:
		Wrapper() {
    
    };
		~Wrapper() {
    
    };
		string pack_way(void) {
    
    
			return "Wrapper pack way";
		}
};

//创建一个表示食物条目的抽象基类接口
class Item {
    
    
	public:
		Item() {
    
    };
		virtual ~Item() {
    
    
			delete tpack;
			tpack = NULL;
		}
		virtual string name(void)=0;    //返回食物的名字
		virtual package *pack(void)=0;  //返回食物的包装方式
		virtual float price(void)=0;    //返回食物的价格

	protected:
		string it_name;   //食物的名字
		package *tpack;   //食物的包装方式
		float it_price;   //食物的价格
};

//创建一个瓶子包装的类继承包装抽象基类
class Bottle : public package {
    
    
	public:
		Bottle() {
    
    };
		~Bottle() {
    
    };
		string pack_way(void) {
    
    
			return "Bottle pack way";
		}
};

//创建素食汉堡继承食物条目抽象基类
class VegBurger : public Item {
    
    
	public:
		VegBurger() {
    
    
			it_name = "VegBurger";
			it_price = 23.5;
			tpack = (package*)new Wrapper();
		}
		~VegBurger() {
    
    };
		float price(void) {
    
    
			return it_price;
		}
		string name(void) {
    
    
			return it_name;
		}
		package *pack(void) {
    
    
			return tpack;
		}
};

//创建素食汉堡继承食物条目抽象基类
class chickenBurger :public Item {
    
    
	public:
		chickenBurger() {
    
    
			it_name = "chickenBurger";
			it_price = 23.5;
			tpack = (package*)new Wrapper();
		}
		~chickenBurger();
		float price(void) {
    
    
			return it_price;
		}
		string name(void) {
    
    
			return it_name;
		}
		package *pack(void) {
    
    
			return tpack;
		}
};

//创建可口可乐继承食物条目抽象基类
class Coke :public Item {
    
    
	public:
		Coke() {
    
    
			it_name = "Coke";
			it_price = 23.5;
			tpack = (package*)new Bottle();
		}
		~Coke();
		float price(void) {
    
    
			return it_price;
		}
		string name(void) {
    
    
			return it_name;
		}
		package *pack(void) {
    
    
			return tpack;
		}
};

//创建一个meal类,是一个套餐的组合
class meal {
    
    
	public:
		meal() {
    
    };
		~meal() {
    
    
			vector<Item*>::iterator it;
			for (it= meal_list.begin(); it!=meal_list.end(); it++) {
    
    
				delete (*it);
				(*it) = NULL;
			}
			cout << "delete meal class" << endl;
		}

		void add_item(Item *it) {
    
    
			meal_list.push_back(it);
		}

		void show_item(void) {
    
    
			vector<Item*>::iterator it;
			for (it = meal_list.begin(); it != meal_list.end(); it++) {
    
    
				cout << "name: " << (*it)->name() << endl;
				cout << "price: " << (*it)->price() << endl;
				cout << "pack: " << (*it)->pack()->pack_way() << endl;
				cout << endl;
			}
		}

	private:
		vector<Item*> meal_list;
};

#endif

//test.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Builder.h"
int main()
{
    
    
	meal t1;
	t1.add_item((Item*)new VegBurger());
	t1.add_item((Item*)new chickenBurger());
	t1.add_item((Item*)new Coke());
 
	t1.show_item();
	return 0;
}

运行结果
在这里插入图片描述

要点总结

  • Builder模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
  • 变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
  • 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs.C#)。

猜你喜欢

转载自blog.csdn.net/weixin_47424753/article/details/132128940
今日推荐