设计模式(C++)-创造型模式-建造者模式

设计模式(C++)-创造型模式-建造者模式

一、建造者模式概述

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你通过一步步构建的方式来创建复杂对象,使得同样的构建过程可以构造出不同表现形式的对象。

解决的问题

  • 当一个类的构造函数参数过多(例如超过4个),或者存在大量可选参数与必选参数的排列组合时:
  • 某类对象的构建过程由多步组成,各步执行细节一直变化,但是所有步骤间的组合关系不变

二、建造模式UML类图

2.1 模式应用例子

要画一个图形,分为画形状和填色两步,这两步固定不会变,但是具体画的形状与颜色会随着需求而经常变化。每次形状与颜色的需求变更时,为了不更改原本类的代码,而是通过扩展新类的方式完成,可以通过构建一个建造者,该建造者只能满足某次需求的要求构建出图形(类似于特定的画笔,只能画出来绿色圆或红色三角),然后在需求变更时,扩展出一个新的建造者即可。

实现方式:

  1. 构建要被构造出来的图形类,并向外部提供能修改该图形类各组成部分的接口;
  2. 构建建造者的抽象类,所有派生的建造者根据自身作用重写接口,返回不同的图形对象;
  3. 构建一个导演类,导演类对象可根据设定的不同构建者,获得不同的图形对象。

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;
}

四、优缺点总结

优点:

  • 将一个复杂对象的构建与它的表示分离,相同的构建过程可以创建不同的表示。
  • 有新的表示可以遵循开放封闭原则,扩展新的类代码完成需求

缺点:

  • 如果构建步骤发生添加或删除,所有建造者类都需要更改代码
相关推荐
likerhood2 小时前
设计模式之建造者模式(Builder Pattern)java版本
java·设计模式·建造者模式
TIEM_692 小时前
C++string接口(下)|修改器、字符串操作、成员常量、非成员函数重载
开发语言·c++
AbandonForce2 小时前
C++ 多态(多态定义 多态应用 多态底层||final override关键字||抽象类)
java·开发语言·c++
进击的荆棘2 小时前
C++起始之路——unordered_map和unordered_set的使用
开发语言·c++·stl·unordered_map·unordered_set
周末也要写八哥2 小时前
前端三大类设计模式学习
学习·设计模式
进击的荆棘2 小时前
C++起始之路——封装红黑树实现map和set
c++·stl·set·map
云深麋鹿2 小时前
C++ | 模板
开发语言·c++
t***54410 小时前
Clang 编译器在 Orwell Dev-C++ 中的局限性
开发语言·c++
jump_jump11 小时前
GetX — Flutter 的瑞士军刀,还是过度封装的陷阱?
flutter·设计模式·前端框架