源码可以在这里找到 大话设计模式C++版
建造小人一
实现画小人的程序
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
createThin(painter);
createFat(painter, 200);
}
void Widget::createThin(QPainter &painter, int x, int y)
{
painter.drawEllipse(QRect(50+x, 20+y, 30, 30));
painter.drawRect(60+x, 50+y, 10, 50);
painter.drawLine(60+x, 50+y, 40+x, 100+y);
painter.drawLine(70+x, 50+y, 90+x, 100+y);
painter.drawLine(60+x, 100+y, 45+x, 150+y);
painter.drawLine(70+x, 100+y, 85+x, 150+y);
}
void Widget::createFat(QPainter &painter, int x, int y)
{
painter.drawEllipse(QRect(50+x, 20+y, 30, 30));
painter.drawEllipse(QRect(45+x, 50+y, 40, 50));
painter.drawLine(50+x, 50+y, 30+x, 100+y);
painter.drawLine(80+x, 50+y, 100+x, 100+y);
painter.drawLine(60+x, 100+y, 45+x, 150+y);
painter.drawLine(70+x, 100+y, 85+x, 150+y);
}
建造小人二
创建两个类,不管谁都可以调用它们
#include <QPainter>
class PersonThinBuilder
{
public:
PersonThinBuilder(QPainter* painter) {
m_painter = painter;
}
void Build(int x=0, int y=0) {
m_painter->drawEllipse(QRect(50+x, 20+y, 30, 30));
m_painter->drawRect(60+x, 50+y, 10, 50);
m_painter->drawLine(60+x, 50+y, 40+x, 100+y);
m_painter->drawLine(70+x, 50+y, 90+x, 100+y);
m_painter->drawLine(60+x, 100+y, 45+x, 150+y);
m_painter->drawLine(70+x, 100+y, 85+x, 150+y);
}
private:
QPainter* m_painter;
};
胖小人类,类似受小人类。
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
PersonThinBuilder personThin(&painter);
PersonFatBuilder personFat(&painter);
personThin.Build();
personFat.Build(150);
}
建造者模式
先抽象一个画小人的基类 PersonBuilder类
class PersonBuilder
{
public:
PersonBuilder(QPainter* painter, int x, int y) {
m_painter = painter;
m_x = x;
m_y = y;
}
virtual void BuildHead() = 0;
virtual void BuildBody() = 0;
virtual void BuildArmLeft() = 0;
virtual void BuildArmRight() = 0;
virtual void BuildLegLeft() = 0;
virtual void BuildLegRight() = 0;
protected:
QPainter* m_painter;
int m_x;
int m_y;
};
具体小人类继承 PersonBuilder类
class PersonThinBuilder : public PersonBuilder
{
public:
PersonThinBuilder(QPainter* painter, int x=0, int y=0) : PersonBuilder(painter, x, y) {}
virtual void BuildHead() {
m_painter->drawEllipse(QRect(50+m_x, 20+m_y, 30, 30));
}
virtual void BuildBody() {
m_painter->drawRect(60+m_x, 50+m_y, 10, 50);
}
virtual void BuildArmLeft() {
m_painter->drawLine(60+m_x, 50+m_y, 40+m_x, 100+m_y);
}
virtual void BuildArmRight() {
m_painter->drawLine(70+m_x, 50+m_y, 90+m_x, 100+m_y);
}
virtual void BuildLegLeft() {
m_painter->drawLine(60+m_x, 100+m_y, 45+m_x, 150+m_y);
}
virtual void BuildLegRight() {
m_painter->drawLine(70+m_x, 100+m_y, 85+m_x, 150+m_y);
}
};
还需要一个指挥画小人的类 PersonDirector类
class PersonDirector
{
private:
std::shared_ptr<PersonBuilder> m_pb;
public:
PersonDirector(std::shared_ptr<PersonBuilder> pb) : m_pb(pb) {}
void CreatePerson() {
m_pb->BuildHead();
m_pb->BuildBody();
m_pb->BuildArmLeft();
m_pb->BuildArmRight();
m_pb->BuildLegLeft();
m_pb->BuildLegRight();
}
};
客户端代码
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
auto ptb = std::shared_ptr<PersonThinBuilder>(new PersonThinBuilder(&painter));
auto pdThin = std::shared_ptr<PersonDirector>(new PersonDirector(ptb));
pdThin->CreatePerson();
auto pfb = std::shared_ptr<PersonFatBuilder>(new PersonFatBuilder(&painter, 100));
auto pdFat = std::shared_ptr<PersonDirector>(new PersonDirector(pfb));
pdFat->CreatePerson();
}
Builder构建器模式 [李建忠C++笔记]
“对象创建”模式
- 通过“对象创建”模式绕开new,来避免对像创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
- 典型模式
- Factory Method
- Abstract Factory
- Prototype
- Builder
动机(Motivation)
- 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
- 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变。
class House {};
class HouseBuilder {
public:
House* GetResult() {
return pHouse;
}
virtual ~HouseBuilder() {}
public:
House* pHouse;
virtual void BuildPart1() = 0;
virtual void BuildPart2() = 0;
virtual bool BuildPart3() = 0;
virtual void BuildPart4() = 0;
virtual void BuildPart5() = 0;
};
class StoneHouse : public House {};
class StoneHouseBuilder : public HouseBuilder {
public:
virtual void BuildPart1() {
}
virtual void BuildPart2() {
}
virtual bool BuildPart3() {
}
virtual void BuildPart4() {
}
virtual void BuildPart5() {
}
};
class HouseDirector {
public:
HouseBuilder* pHouseBuilder;
HouseDirector(HouseBuilder* pHouseBuilder) {
this->pHouseBuilder = pHouseBuilder;
}
House* Construct() {
pHouseBuilder->BuildPart1();
for (int i = 0; i < 4; i++) {
pHouseBuilder->BuildPart2();
}
bool flag = pHouseBuilder->BuildPart3();
if (flag) {
pHouseBuilder->BuildPart4();
}
pHouseBuilder->BuildPart5();
return pHouseBuilder->GetResult();
}
};
int main()
{
StoneHouseBuilder* stoneHouseBuilder = new StoneHouseBuilder();
HouseDirector* pHouseDirector = new HouseDirector(stoneHouseBuilder);
pHouseDirector->Construct();
}
要点总结
- Builder模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
- 变化点在哪里,封装哪里——Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
- 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#)
|