设计模式(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;
}

四、优缺点总结

优点:

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

缺点:

  • 如果构建步骤发生添加或删除,所有建造者类都需要更改代码
相关推荐
咖啡八杯10 小时前
GoF设计模式——策略模式
java·后端·spring·设计模式
博客180021 小时前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝
郝学胜_神的一滴1 天前
CMake 026:属性体系精讲、四大作用域全解 & 实战代码落地
c++·cmake
众少成多积小致巨2 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
槑有老呆2 天前
别再手搓 Prompt 了,那个叫"手动挡循环"
设计模式
用户6919026813393 天前
Vibe Coding 开发项目的基本范式
人工智能·设计模式·代码规范
怕浪猫4 天前
领域特定语言(Domain-Specific Language, DSL)
设计模式·程序员·架构
Larcher6 天前
AI Loop:让AI像人一样自主完成任务的核心机制
javascript·人工智能·设计模式
clint4566 天前
C++进阶(1)——前景提要
c++