有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。建造者模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定。
创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
建造者(Builder)模式:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
建造者模式的特点如下:
A、建造者模式是将一个复杂对象的创建过程给封装起来,客户只需要知道可以利用对象名或者类型就能够得到一个完整的对象实例,而不需要关心对象的具体创建过程。
B、建造者模式将对象的创建过程与对象本身隔离开了,使得细节依赖于抽象,符合依赖倒置原则。可以使用相同的创建过程来创建不同的产品
建造者(Builder)模式的主要角色如下:
产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个部件。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
场景:软件产品需要经过 需求分析、概要设计、详细设计、编码、测试、交付等过程。不同的软件的过程是一样,但是每个步骤的内容是不一样。
话不多说直接上代码:
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <vector>
#include<string>
using namespace std;
class Software
{
public:
vector<string> parts;
~Software()
{
parts.clear();
}
public:
void Add(string part)
{
parts.push_back(part);
}
void Show()
{
for (int i=0;i<parts.size();i++)
{
cout<< parts[i]<<endl;
}
}
};
class SoftWareBuilder
{
public:
SoftWareBuilder(){};
virtual void RequirementAnalysis() {};
virtual void OutlineDesign(){};
virtual void DetailedDesign() {};
virtual void Code(){};
virtual void Test(){};
virtual void SoftwareDelivery(){};
virtual void Show(){};
virtual Software* GetSoftware()
{
return NULL;
}
};
class AcousticBuilder:public SoftWareBuilder
{
public:
AcousticBuilder()
{
m_Software = new Software();
}
~AcousticBuilder()
{
if (m_Software != NULL)
{
delete m_Software;
m_Software = NULL;
}
}
void RequirementAnalysis()
{
m_Software->Add("超声软件需求分析");
}
void OutlineDesign()
{
m_Software->Add("超声软件概要设计");
}
void DetailedDesign()
{
m_Software->Add("超声软件详细设计");
}
void Code()
{
m_Software->Add("超声软件编码");
}
void Test()
{
m_Software->Add("超声软件测试");
}
void SoftwareDelivery()
{
m_Software->Add("超声软件交付");
}
Software* GetSoftware()
{
return m_Software;
}
void Show()
{
m_Software->Show();
}
private:
Software* m_Software;
};
class StructureBuilder:public SoftWareBuilder
{
public:
StructureBuilder()
{
m_Software = new Software();
}
~StructureBuilder()
{
if (m_Software != NULL)
{
delete m_Software;
m_Software = NULL;
}
}
void RequirementAnalysis()
{
m_Software->Add("结构软件需求分析");
}
void OutlineDesign()
{
m_Software->Add("结构软件概要设计");
}
void DetailedDesign()
{
m_Software->Add("结构软件详细设计");
}
void Code()
{
m_Software->Add("结构软件编码");
}
void Test()
{
m_Software->Add("结构软件测试");
}
void SoftwareDelivery()
{
m_Software->Add("结构软件交付");
}
Software* GetSoftware()
{
return m_Software;
}
void Show()
{
m_Software->Show();
}
private:
Software* m_Software;
};
class Leader
{
public:
Leader(SoftWareBuilder* pSoftWareBuilder)
{
m_pSoftwareBuilder = pSoftWareBuilder;
}
void Construct()
{
m_pSoftwareBuilder->RequirementAnalysis();
m_pSoftwareBuilder->OutlineDesign();
m_pSoftwareBuilder->DetailedDesign();
m_pSoftwareBuilder->Code();
m_pSoftwareBuilder->Test();
m_pSoftwareBuilder->SoftwareDelivery();
}
void Show()
{
m_pSoftwareBuilder->Show();
}
SoftWareBuilder* m_pSoftwareBuilder;
};
int _tmain(int argc, _TCHAR* argv[])
{
SoftWareBuilder* pSoftWareBuilder = new SoftWareBuilder();
pSoftWareBuilder = new StructureBuilder();
Leader* pLeader = new Leader(pSoftWareBuilder);
pLeader->Construct();
Software* pSoftware = pSoftWareBuilder->GetSoftware();
pSoftware->Show();
delete pSoftware;
delete pLeader;
delete pSoftWareBuilder;
system("pause");
return 0;
}
缺点如下:
A、要求构建产品的步骤(算法)是不能剧烈变化的,最好是不变的,影响了灵活度。
B、如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现内部复杂的变化,导致系统变得很庞大。