首先看看下面的代码,是否可以发现有什么不好的地方?是的在没有建造者模式的代码中,很容易遗漏某些部分。
Main函数:
#include <QApplication>
#include "Mainimpl.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Mainimpl* pMainWindow = new Mainimpl();
pMainWindow->show();
return app.exec();
}
#pragma once
#include <QDialog>
#include <QPen>
#include <QColor>
#include <QPainter>
class Mainimpl :
public QDialog
{
public:
void paintEvent(QPaintEvent*)
{
QPen pen;
pen.setWidth(10);
pen.setStyle(Qt::SolidLine);
QColor color(100,100,100);
pen.setColor(color);
QPainter paint(this);
paint.setPen(pen);
//画身体的各个部分
paint.drawEllipse(50,20,30,30);
paint.drawRect(60,50,10,50);
paint.drawLine(60,50,40,100);
paint.drawLine(70,50,90,100);
paint.drawLine(60,100,45,150);
paint.drawLine(70,100,85,150);
};
};
1.中式的快餐为什么每回味不同?这是由于我们要吃的菜都依赖于厨师。其实根据依赖倒转原则,抽象不应该依赖细节,细节应该依赖于抽象。肯德基麦当劳的工作流程就是一种抽象的流程,具体放什么配料烤多长时间等细节依赖于这个抽象。
2.建造者模式(Builder)将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。
3.如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到他们,而具体建造的过程和细节就不需知道了。
4.在构建小人的时候,要构建头,身体,左手,右手,左脚,右脚。为了不忘记其中的每一步,应该建一个抽象类,在这个抽象类中,分别加入构建头,身体,左手,右手,左脚,右脚的抽象函数。这样就不会忘记或者少构建一个了。
5.建造者模式中一个很重要的类:指挥者(Director),用它来控制建造过程,也用它来隔离用户与建造过程的关联。
PersonBuilder.h:有了建造者模式以后,建造头,手,身体等等都可以抽象化了
#pragma once
#include <QWidget>
#include <QPen>
#include <QPainter>
//建造抽象者
class PersonBuilder
{
public:
virtual void BuildHead(QPainter& painter) = 0;
virtual void BuildBody(QPainter& painter) = 0;
virtual void BuildArmLeft(QPainter& painter) = 0;
virtual void BuildArmRight(QPainter& painter) = 0;
virtual void BuildLegLeft(QPainter& painter) = 0;
virtual void BuildLegRight(QPainter& painter) = 0;
virtual ~PersonBuilder(void){};
};
//瘦子的建造者
class PersonThinBuilder :public PersonBuilder
{
public:
void BuildHead(QPainter& painter)
{
painter.drawEllipse(50,20,30,30);
};
void BuildBody(QPainter& painter)
{
painter.drawRect(60,50,10,50);
};
void BuildArmLeft(QPainter& painter)
{
painter.drawLine(60,50,40,100);
};
void BuildArmRight(QPainter& painter)
{
painter.drawLine(70,50,90,100);
};
void BuildLegLeft(QPainter& painter)
{
painter.drawLine(60,100,45,150);
};
void BuildLegRight(QPainter& painter)
{
painter.drawLine(70,100,85,150);
};
};
//胖子的建造者
class PersonFatBuilder :public PersonBuilder
{
public:
void BuildHead(QPainter& painter)
{
painter.drawEllipse(50,20,30,30);
};
void BuildBody(QPainter& painter)
{
painter.drawRect(45,50,40,50);
};
void BuildArmLeft(QPainter& painter)
{
painter.drawLine(50,50,30,100);
};
void BuildArmRight(QPainter& painter)
{
painter.drawLine(80,50,100,100);
};
void BuildLegLeft(QPainter& painter)
{
painter.drawLine(60,100,45,150);
};
void BuildLegRight(QPainter& painter)
{
painter.drawLine(70,100,85,150);
};
};
//指挥者
class PersonDirector :public QWidget
{
public:
PersonDirector(PersonBuilder* p)
{
m_pPersonBuilder = p;
};
~PersonDirector()
{
if (m_pPersonBuilder != NULL)
{
delete m_pPersonBuilder;
m_pPersonBuilder = NULL;
}
};
void CreatePerson(void)
{
this->show();
};
void paintEvent(QPaintEvent*)
{
QPen pen;
pen.setWidth(10);
pen.setStyle(Qt::SolidLine);
QPainter paint(this);
paint.setPen(pen);
m_pPersonBuilder->BuildHead(paint);
m_pPersonBuilder->BuildBody(paint);
m_pPersonBuilder->BuildArmLeft(paint);
m_pPersonBuilder->BuildArmRight(paint);
m_pPersonBuilder->BuildLegLeft(paint);
m_pPersonBuilder->BuildLegRight(paint);
};
private:
PersonBuilder* m_pPersonBuilder;
};
#include <QApplication>
#include "PersonBuilder.h"
int _tmain(int argc, _TCHAR* argv[])
{
QApplication app(argc, argv);
PersonBuilder* thinPerson = new PersonThinBuilder();
PersonDirector director(thinPerson);
director.CreatePerson();
PersonBuilder* fatPerson = new PersonFatBuilder();
PersonDirector director2(fatPerson);
director2.CreatePerson();
return app.exec();
}
代码相关联的图如下图表示:
6.建造者模式主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
7.建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式。
8.如果大排档作炒面的老板知道建造者模式,它就明白,盐是一定要放的,不然编译就通不过。
下面是净化版的建造者模式,建造的各个部分用了向量结构来表示。首先是建造的实现者:
#pragma once
#include <vector>
#include <string>
#include <iostream>
class Product
{
public:
~Product()
{
m_parts.clear();
};
void Add(std::string myPart)
{
m_parts.push_back(myPart);
};
void Show()
{
std::cout << "开始表示." << std::endl;
if (!m_parts.empty())
{
std::vector<std::string>::iterator iter = m_parts.begin();
while (iter != m_parts.end())
{
std::cout << (*iter) << std::endl;
++iter;
}
}
};
private:
std::vector<std::string> m_parts;
};
接来下是建造类。Builder.h:
#pragma once
#include "Product.h"
class Builder
{
public:
virtual void BuilderPartA(void) = 0;
virtual void BuilderPartB(void) = 0;
virtual Product* GetResult(void) = 0;
};
class ConcreteBuilder1 : public Builder
{
public:
ConcreteBuilder1()
{
m_pProduct = new Product();
}
~ConcreteBuilder1()
{
if (m_pProduct != NULL)
{
delete m_pProduct;
m_pProduct = NULL;
}
}
void BuilderPartA(void)
{
m_pProduct->Add("PartA");
};
void BuilderPartB(void)
{
m_pProduct->Add("PartB");
};
Product* GetResult(void)
{
return m_pProduct;
};
private:
Product* m_pProduct;
};
class ConcreteBuilder2 : public Builder
{
public:
ConcreteBuilder2()
{
m_pProduct = new Product();
}
~ConcreteBuilder2()
{
if (m_pProduct != NULL)
{
delete m_pProduct;
m_pProduct = NULL;
}
}
void BuilderPartA(void)
{
m_pProduct->Add("PartX");
};
void BuilderPartB(void)
{
m_pProduct->Add("PartY");
};
Product* GetResult(void)
{
return m_pProduct;
};
private:
Product* m_pProduct;
};
#pragma once
#include "Builder.h"
class Director
{
public:
void Construct(Builder* builder)
{
builder->BuilderPartA();
builder->BuilderPartB();
};
};
//这里是指挥者,它对细节已经知道的很少了。