设计模式(C++)-创造型模式-建造者模式
一、建造者模式概述
建造者模式(Builder Pattern)是一种创建型设计模式,它允许你通过一步步构建的方式来创建复杂对象,使得同样的构建过程可以构造出不同表现形式的对象。
解决的问题
- 当一个类的构造函数参数过多(例如超过4个),或者存在大量可选参数与必选参数的排列组合时:
- 某类对象的构建过程由多步组成,各步执行细节一直变化,但是所有步骤间的组合关系不变
二、建造模式UML类图
2.1 模式应用例子
要画一个图形,分为画形状和填色两步,这两步固定不会变,但是具体画的形状与颜色会随着需求而经常变化。每次形状与颜色的需求变更时,为了不更改原本类的代码,而是通过扩展新类的方式完成,可以通过构建一个建造者,该建造者只能满足某次需求的要求构建出图形(类似于特定的画笔,只能画出来绿色圆或红色三角),然后在需求变更时,扩展出一个新的建造者即可。
实现方式:
- 构建要被构造出来的图形类,并向外部提供能修改该图形类各组成部分的接口;
- 构建建造者的抽象类,所有派生的建造者根据自身作用重写接口,返回不同的图形对象;
- 构建一个导演类,导演类对象可根据设定的不同构建者,获得不同的图形对象。
2.2 UML类图

三、代码实现
cpp
//builder.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
//要构建的对象
class graphic {
public:
graphic() {};
//常变属性设置接口
void setShape(const string&shape);
void setColor(const string&color);
void show();
private:
string m_shape;
string m_color;
};
//建造者抽象类
class builder {
public:
builder() :m_pgraphic(nullptr) {};
//创建空白图像对象
void createGraphic();
graphic* getGraphic();
// 留给派生类实现的描绘过程
virtual void drawShape() = 0;
virtual void drawColor() = 0;
protected:
graphic* m_pgraphic;
};
class greencirclebuilder : public builder {
public:
virtual void drawShape();
virtual void drawColor();
};
class redrectanglebuilder : public builder {
public:
virtual void drawShape();
virtual void drawColor();
};
class bluetrianglebuilder : public builder {
public:
virtual void drawShape();
virtual void drawColor();
};
//导演类
class director {
public:
director() :m_pbuilder(nullptr) {};
// 根据需求设置对应的建造者
void setBuilder(builder& pBuilder);
// 通过建造者获得描绘完成的图形
graphic* drawGraphic();
private:
builder* m_pbuilder;
};
void testBuilder();
//builder.cc
#include "builder.h"
//常变属性设置接口
void graphic::setShape(const string&shape) {
m_shape = shape;
}
void graphic::setColor(const string&color) {
m_color = color;
}
void graphic::show() {
cout << m_color << m_shape << endl;
}
//创建空白图像对象
void builder::createGraphic() {
if (NULL == m_pgraphic) {
m_pgraphic = new graphic();
}
}
graphic* builder::getGraphic() {
return m_pgraphic;
}
void greencirclebuilder::drawShape() {
if (NULL != m_pgraphic) {
m_pgraphic->setShape("circle");
}
}
void greencirclebuilder::drawColor() {
if (NULL != m_pgraphic) {
m_pgraphic->setColor("green");
}
}
void redrectanglebuilder::drawShape() {
if (NULL != m_pgraphic) {
m_pgraphic->setShape("rectang");
}
}
void redrectanglebuilder::drawColor() {
if (NULL != m_pgraphic) {
m_pgraphic->setColor("red");
}
}
void bluetrianglebuilder::drawShape() {
if (NULL != m_pgraphic) {
m_pgraphic->setShape("triangle");
}
}
void bluetrianglebuilder::drawColor() {
if (NULL != m_pgraphic) {
m_pgraphic->setColor("blue");
}
}
// 根据需求设置对应的建造者
void director::setBuilder(builder& pBuilder){
m_pbuilder = &pBuilder;
}
//通过建造者获得描绘完成的图形
graphic* director::drawGraphic() {
if (NULL == m_pbuilder) {
return NULL;
}
//建造过程为不变的因素
m_pbuilder->createGraphic();
m_pbuilder->drawColor();
m_pbuilder->drawShape();
return m_pbuilder->getGraphic();
}
void testBuilder() {
cout << "=================builder start===============" << endl;
director MyDirector;
// 根据导演的不同需求,分别设置不同的建造者,获得满足需求的图形
greencirclebuilder BuilderGC; // 绿色圆形的建造者
MyDirector.setBuilder(BuilderGC);
graphic* pGraphicGC = MyDirector.drawGraphic(); // 导演使用建造者画图
pGraphicGC->show();
redrectanglebuilder BuilderRB; // 红色矩形的建造者
MyDirector.setBuilder(BuilderRB);
graphic* pGraphicRB = MyDirector.drawGraphic(); // 导演使用建造者画图
pGraphicRB->show();
bluetrianglebuilder BuilderBT; // 蓝色三角的建造者
MyDirector.setBuilder(BuilderBT);
graphic* pGraphicBT = MyDirector.drawGraphic(); // 导演使用建造者画图
pGraphicBT->show();
// 资源回收
if (NULL == pGraphicGC) {
delete pGraphicGC;
pGraphicGC = NULL;
}
if (NULL == pGraphicRB) {
delete pGraphicRB;
pGraphicRB = NULL;
}
if (NULL == pGraphicBT) {
delete pGraphicBT;
pGraphicBT = NULL;
}
cout << "=================builder end===============" << endl;
}
四、优缺点总结
优点:
- 将一个复杂对象的构建与它的表示分离,相同的构建过程可以创建不同的表示。
- 有新的表示可以遵循开放封闭原则,扩展新的类代码完成需求
缺点:
- 如果构建步骤发生添加或删除,所有建造者类都需要更改代码