示例问题:
解决一个问题的步骤及顺序都相同,但是每一个步骤所用的方法可能不同。设计一种模式解决该问题
分析:
要保证每个步骤都实现,且顺序固定。可灵活变换步骤的实现方法。这种模式要注意固定步骤及顺序,做到避免调用者去使用每个步骤而导致出错(遗漏步骤,或者弄错顺序)。
解决方案:
Builder.h
该文件内,实现了建造者的基类CBaseBuilder了,和3个具体的建造者(继承建造者基类)。还有一个指导建造的类CBuilderDirector(该类封装了建造者的建造流程,保证步骤固定,顺序固定,保证外部调用者不用关心建造步骤和顺序)。
若有新的建造方法(步骤的方法),则新增子类继承CBaseBuilder,在步骤中实现新的方法即可。
#pragma once
#include <iostream>
class CBaseBuilder
{
public:
CBaseBuilder()
{
}
virtual ~CBaseBuilder()
{
}
//步骤一
virtual void Procedure1() = 0;
//步骤二
virtual void Procedure2() = 0;
//步骤三
virtual void Procedure3() = 0;
};
class CConcreteBuilderA : public CBaseBuilder
{
public:
CConcreteBuilderA()
{
}
virtual ~CConcreteBuilderA()
{
}
//A方法步骤一
void Procedure1()
{
std::cout << "这是A方法的步骤一" << std::endl;
}
//A方法步骤二
virtual void Procedure2()
{
std::cout << "这是A方法的步骤二" << std::endl;
}
//A方法步骤三
virtual void Procedure3()
{
std::cout << "这是A方法的步骤三" << std::endl;
}
};
class CConcreteBuilderB : public CBaseBuilder
{
public:
CConcreteBuilderB()
{
}
virtual ~CConcreteBuilderB()
{
}
//A方法步骤一
void Procedure1()
{
std::cout << "这是B方法的步骤一" << std::endl;
}
//A方法步骤二
virtual void Procedure2()
{
std::cout << "这是B方法的步骤二" << std::endl;
}
//A方法步骤三
virtual void Procedure3()
{
std::cout << "这是B方法的步骤三" << std::endl;
}
};
class CConcreteBuilderC : public CBaseBuilder
{
public:
CConcreteBuilderC()
{
}
virtual ~CConcreteBuilderC()
{
}
//A方法步骤一
void Procedure1()
{
std::cout << "这是C方法的步骤一" << std::endl;
}
//A方法步骤二
virtual void Procedure2()
{
std::cout << "这是C方法的步骤二" << std::endl;
}
//A方法步骤三
virtual void Procedure3()
{
std::cout << "这是C方法的步骤三" << std::endl;
}
};
class CBuilderDirector
{
public:
CBuilderDirector()
{
}
virtual ~CBuilderDirector()
{
}
void SetBuilder(CBaseBuilder* pBaseBuilder)
{
m_pBaseBuilder = pBaseBuilder;
}
void Execute()
{
m_pBaseBuilder->Procedure1();
m_pBaseBuilder->Procedure2();
m_pBaseBuilder->Procedure3();
}
private:
CBaseBuilder* m_pBaseBuilder;
};
main.cpp
// main.cpp : 定义控制台应用程序的入口点。
//
#include "Builder.h"
int main()
{
CBuilderDirector BuildDirector;
CConcreteBuilderA* pConcreteBuilderA = new(std::nothrow) CConcreteBuilderA();
BuildDirector.SetBuilder(pConcreteBuilderA);
std::cout << "建造方法A执行" << std::endl;
BuildDirector.Execute();
CConcreteBuilderB* pConcreteBuilderB = new(std::nothrow) CConcreteBuilderB();
BuildDirector.SetBuilder(pConcreteBuilderB);
std::cout << "建造方法B执行" << std::endl;
BuildDirector.Execute();
CConcreteBuilderC* pConcreteBuilderC = new(std::nothrow) CConcreteBuilderC();
BuildDirector.SetBuilder(pConcreteBuilderC);
std::cout << "建造方法C执行" << std::endl;
BuildDirector.Execute();
if (nullptr != pConcreteBuilderA)
{
delete pConcreteBuilderA;
pConcreteBuilderA = nullptr;
}
if (nullptr != pConcreteBuilderB)
{
delete pConcreteBuilderB;
pConcreteBuilderB = nullptr;
}
if (nullptr != pConcreteBuilderC)
{
delete pConcreteBuilderC;
pConcreteBuilderC = nullptr;
}
system("pause");
return 0;
}
执行结果:
建造者模式的使用:
建造者模式(又叫生成器模式),将一个复杂对象的构建与它的表示分离,是的同样的构建过程可以创建不同的表示。
建造者模式主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所有若需要改变一个产品的内部表示,只需要再定义个具体的建造者就可以了。
何时使用建造者模式:
建造者模式是当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式。
返回目录:设计模式(C++实现)(总)