zoukankan      html  css  js  c++  java
  • 设计模式那点事--建造者模式

             概念

            建造者模式Builder)。将一个复杂对象的创建与它的表示分离,使得相同的构建过程能够创建不同的表示。

            建造者模式能够将一个产品的内部表象与产品的生成过程切割开来,从而能够使一个建造过程生成具有不同的内部表象的产品对象。

    我们仅仅需指定须要建造的类型就能够得到它们,而详细建造的过程和细节就不需知道了。

            样例

            一个鲜活简单的样例总能让人轻松地理解晦涩的概念。我们来看看一个关于构建汽车的建造者模式。

            我们知道。汽车一般由轮胎,引擎和车身组成。就像宝马(BMW)。法拉利(Ferrali)和奔驰(Benz)三辆汽车,它们也是由这三种东西组成的,仅仅只是构成模块价格不同。

            对于它们来说。尽管组成模块价格不同,可是构建汽车都包括这三种东西,是一种公共操作。

    于是。能够创建一个抽象父亲汽车构建类(CarBuilder),声明三个构建函数virtual void BuildWheel等的接口

    然后创建三个详细汽车构建子类:BMWBuilder,FerraliBuilder和BenzBuilder。用于详细汽车的构建,并提供返回详细汽车产品对象的接口。

    它们分别继承于CarBuilder,每一个子类实现父类模块的个性化构建。

            然后再定义一个构建汽车指导者CarDirector。用于控制汽车建造过程,隔离用户与建造过程的关联。最后定义一个产品类Product,用于显示终于的生成汽车产品。

           角色

           1、建造者(Builder):为创建一个产品对象的各个部件指定抽象接口,如CarBuilder

           2、详细建造者(ConcreteBuilder):实现Builder的接口以构造和装配该产品的各个部件,定义并明白它所创建的表示,提供一个获取汽车成品对象的接口,如BMWBilder

           3、指示领导者(Director):构造一个使用Builder接口的对象,用于控制建造过程,隔离用户与建造过程的关联,如CarDirector。

           4、详细产品(Product):表示被构造的复杂对象。如BMW汽车。

           UML


       代码:

    #pragma warning(disable : 4786)
    
    #include <iostream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    //详细产品类
    class Product
    {
    public:
    	vector<string> st;
    public:
    	void AddParts(string sValue)
    	{
    		st.push_back(sValue);
    	}
    	
    	void Show()
    	{
    		for (vector<string>::iterator stIter=st.begin(); stIter!=st.end(); stIter++)
    		{
    			cout<<*stIter<<endl;
    		}
    	}
    };
    
    //建造者类
    class CarBuilder
    {
    public:
    	virtual void BuildWheel()
    	{
    		cout<<"CarBuilder:bulid wheel."<<endl; 
    	}
    
    	virtual void BuildEngine()
    	{
    		cout<<"CarBuilder:bulid engine."<<endl; 
    	}
    
    	virtual void BuildBody()
    	{
    		cout<<"CarBuilder:bulid body."<<endl; 
    	}
    };
    
    //详细builder类,用于建造出详细产品
    //实现CarBuilder的接口以构造和装配该产品的各个部件,定义并明白它所创建的表示,并 提供一个检索产品的接口
    class BMWBuilder:public CarBuilder
    {
    public:
    	Product product;
    public:
    	void BuildWheel()
    	{
    		product.AddParts("BMW:bulid wheel.");
    	}
    	
    	void BuildEngine()
    	{
    		product.AddParts("BMW:bulid engine.");
    	}
    	
    	void BuildBody()
    	{
    		product.AddParts("BMW:bulid body.");
    	}
    	
    	Product GetProduct()
    	{
    		return product;
    	}
    };
    
    class FerraliBuilder:public CarBuilder
    {
    public:
    	Product product;
    public:
    	void BuildWheel()
    	{
    		product.AddParts("Ferrali:bulid wheel.");
    	}
    	
    	void BuildEngine()
    	{
    		product.AddParts("Ferrali:bulid engine.");
    	}
    	
    	void BuildBody()
    	{
    		product.AddParts("Ferrali:bulid body.");
    	}
    	
    	Product GetProduct()
    	{
    		return product;
    	}
    };
    
    class BenzBuilder:public CarBuilder
    {
    public:
    	Product product;
    public:
    	void BuildWheel()
    	{
    		product.AddParts("Benz:bulid wheel.");
    	}
    	
    	void BuildEngine()
    	{
    		product.AddParts("Benz:bulid engine.");
    	}
    	
    	void BuildBody()
    	{
    		product.AddParts("Benz:bulid body.");
    	}
    
    	Product GetProduct()
    	{
    		return product;
    	}
    };
    
    //指挥者,用于控制建造过程,隔离用户与建造过程的关联
    class CarDirector
    {
    private:
    	CarBuilder* cb;
    public:
    	CarDirector(CarBuilder* cb)
    	{
    		this->cb = cb;
    	}
    
    	~CarDirector()
    	{
    		if (cb!=NULL)
    		{
    			delete cb;
    			cb = NULL;
    		}
    	}
    
    	void CreateCar()
    	{
    		cb->BuildWheel();
    		cb->BuildEngine();
    		cb->BuildBody();
    	}
    };
    
    int main()
    {
    	int iTag=0;
    	Product product;
    	
    	cout<<"----建造者模式開始----"<<endl;
    	cout<<"BMW:1,Ferrali:2,Benz:3"<<endl;
    	cout<<"请输入您想要构建的汽车:";
    	cin>>iTag;
    
    	if(iTag==1)
    	{
    		BMWBuilder* bb= new BMWBuilder;
    		CarDirector cd(bb);
    		cd.CreateCar();
    		product = bb->GetProduct();
    		product.Show();
    	}
    	else if(iTag==2)
    	{
    		FerraliBuilder* fb= new FerraliBuilder;
    		CarDirector cd(fb);
    		cd.CreateCar();
    		product = fb->GetProduct();
    		product.Show();
    	}
    	else if(iTag==3)
    	{
    		BenzBuilder* bb= new BenzBuilder;
    		CarDirector cd(bb);
    		cd.CreateCar();
    		product = bb->GetProduct();
    		product.Show();
    	}
    
    	cout<<"----建造者模式结束----"<<endl;
    	
    	return 1;
    }

        发散

         我们知道实现C++的多态有三种方法:函数重载,模板函数和虚函数。

    虚函数实现的多态称为动态多态。上面代码有下面特点:

         1、子类的对象转换给父类的对象如CarBuilder* cb= new BMWBuilder,我们称为向上转型。

    它是安全的,自己主动完毕,而且会丢失子类型的信息;

         2、为了解决子类型信息丢失的问题(子类对象转换给父类),父类必须实现了一个虚函数BuildWheel

         3、子类有全然同样的BuildWheel函数,覆盖重写父类的虚函数BuildWheel,这样便能实现动态多态了(否则仅仅能用指针或引用了)。

        应用场景

         1、当创建一些复杂对象,这些对象内部构建间的建造顺序一般是稳定的。但对象内部的构建面临着复杂的变化;

         2、当构造过程必须同意被构造的对象有不同表示时。

        长处

        使得建造代码与表示代码分离,因为建造者隐藏了该产品是怎样组装的,所以若须要改变一个产品的内部表示。仅仅须要再定义一个详细的建造者就能够了,减少耦合性。


  • 相关阅读:
    查询Python支持的.whl格式
    内置模块之os
    内置标准库之time
    迭代器(iterator)
    STM32F103和SIM800L打造低成本短信转发系统(五):控制程序
    STM32F103和SIM800L打造低成本短信转发系统(四):MDK-ARM
    STM32F103和SIM800L打造低成本短信转发系统(三):STM32CubeMX
    STM32F103和SIM800L打造低成本短信转发系统(二):软件安装篇
    STM32F103和SIM800L打造低成本短信转发系统(一):硬件篇
    处理SIM800L模块的时间字符串之URL编码(百分号编码)
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7099905.html
Copyright © 2011-2022 走看看