重拾设计模式--建造者模式

文章目录

建造者模式(Builder Pattern)概述

定义:

建造者模式是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。也就是说,它把对象的创建逻辑和表示逻辑分离开来,让代码结构更加清晰,便于维护和扩展。

建造者模式UML图

作用:

便于创建复杂对象:对于那些具有多个属性、构造过程比较复杂的对象,使用建造者模式可以分步来构建对象,使创建过程更有条理。例如,创建一个包含多个部件的电脑对象,要配置 CPU、内存、硬盘等多种组件,通过建造者模式能清晰地完成配置过程。

提高代码的可维护性和可读性:把对象构建的各个步骤封装在不同的方法中,相比于在构造函数中罗列大量参数或者在一个方法里写复杂的初始化逻辑,代码结构更加清晰,后续阅读和维护代码时更容易理解对象的构建流程。

实现不同的构建配置:可以通过不同的建造者实现来创建对象的不同配置版本,比如对于一款游戏角色,可以创建不同属性配置的角色实例,满足不同场景需求。

建造者模式的结构

产品(Product):

这是最终要创建的复杂对象,它通常包含多个部件或者属性,比如上述提到的电脑对象,其内部有 CPU、内存、硬盘等不同的成员变量来构成完整的电脑实体。

抽象建造者(Builder):

它定义了创建产品各个部件的抽象方法,以及返回最终产品对象的抽象方法。比如对于电脑的抽象建造者,会有抽象的配置 CPU、配置内存等方法,还有获取构建好的电脑的抽象方法。

具体建造者(Concrete Builder):

实现了抽象建造者中定义的抽象方法,具体地来构建产品的各个部件,按照特定的逻辑和配置完成产品的组装,每个具体建造者可以创建出具有不同配置特点的产品。

指挥者(Director):

它负责指挥建造者进行对象的构建,通过调用建造者的相关方法来按顺序完成产品的创建过程,不过它并不关心具体的构建细节,只是协调构建步骤。

C++ 代码示例1

以下以创建一个简单的电脑对象为例来展示建造者模式的代码实现:

cpp 复制代码
#include<iostream>
#include<string>

// 产品类:电脑
class Computer
{
private:
	std::string cpu;
	int memory;
	int hardDisk;
public:
	void setCpu(const std::string& cpu)
	{
		this->cpu = cpu;
	}
	void setMemory(int memory)
	{
		this->memory = memory;
	}
	void setHardDisk(int hardDisk)
	{
		this->hardDisk = hardDisk;
	}

	void showInfo()
	{
		std::cout << "CPU: " << cpu << std::endl;
		std::cout << "Memory: " << memory << "GB" << std::endl;
		std::cout << "Hard Disk: " << hardDisk << "GB" << std::endl;
	}
};

// 抽象建造者类
class ComputerBuilder
{
public:
	virtual void buildCpu() = 0;
	virtual void buildMemory() = 0;
	virtual void buildHardDisk() = 0;
	virtual Computer* getComputer() = 0;
};

// 具体建造者类,创建高配电脑
class HighEndComputerBuilder :public ComputerBuilder 
{
private:
	Computer* computer;
public:
	HighEndComputerBuilder() 
	{
		computer = new Computer();
	}
	void buildCpu() override
	{
		computer->setCpu("Intel Core i9");
	}
	void buildMemory() override
	{
		computer->setMemory(32);
	}
	void buildHardDisk() override
	{
		computer->setHardDisk(1024);
	}
	Computer* getComputer() override
	{
		return computer;
	}
};

// 具体建造者类,创建低配电脑
class LowEndComputerBuilder :	public ComputerBuilder
{
private:
	Computer* computer;
public:
	LowEndComputerBuilder()
	{
		computer = new Computer();
	}
	void buildCpu() override 
	{
		computer->setCpu("Intel Core i3");
	}
	void buildMemory() override 
	{
		computer->setMemory(8);
	}
	void buildHardDisk() override
	{
		computer->setHardDisk(256);
	}
	Computer* getComputer() override
	{
		return computer;
	}
};

// 指挥者类
class Director
{
private:
	ComputerBuilder* builder;
public:
	void setBuilder(ComputerBuilder* builder) 
	{
		this->builder = builder;
	}
	Computer* construct()
	{
		builder->buildCpu();
		builder->buildMemory();
		builder->buildHardDisk();
		return builder->getComputer();
	}
};

int main()
{
	Director director;

	// 创建高配电脑
	HighEndComputerBuilder highEndBuilder;
	director.setBuilder(&highEndBuilder);
	Computer* highEndComputer = director.construct();
	highEndComputer->showInfo();

	// 创建低配电脑
	LowEndComputerBuilder lowEndBuilder;
	director.setBuilder(&lowEndBuilder);
	Computer* lowEndComputer = director.construct();
	lowEndComputer->showInfo();

	delete highEndComputer;
	delete lowEndComputer;

	return 0;
}

在上述代码中:

Computer类就是产品类,代表要构建的电脑对象,有设置各部件属性和展示自身信息的方法。

ComputerBuilder是抽象建造者,定义了构建电脑各部件及获取电脑对象的抽象方法。

HighEndComputerBuilder和LowEndComputerBuilder是具体建造者,分别按照高配和低配的配置来构建电脑对象。

Director类作为指挥者,通过调用建造者的方法来协调完成电脑对象的构建过程,最终客户端代码(main函数中)可以方便地通过指挥者和不同的建造者配合,创建出不同配置的电脑对象,整个创建过程条理清晰,易于扩展和维护。

C++示例代码2

cpp 复制代码
#include<iostream>
#include<list>
#include<string>
using namespace std;

class product
{
	list<string>ls;
public:
	void add(string m_str)
	{
		ls.push_back(m_str);
	}
	void show()
	{
		list<string>::iterator itr = ls.begin();
		for(;itr!=ls.end();++itr)
		{
			cout<<*itr<<endl;
		}
	}
};
class builder
{
public:
	virtual void head(){};
	virtual void body(){};
	virtual void leg(){};
	virtual void hand(){};
	virtual product getresult(){product s;return s;};
};

class  conbuild1:public builder
{
private:
	product *m_product;
public:
	conbuild1()
	{
		m_product = new product();
	}
	void head()
	{
		m_product->add("1的头");
	}
	void body()
	{
		m_product->add("1的身体");
	}
	void leg()
	{
		m_product->add("1的腿");
	}
	void hand()
	{
		m_product->add("1的手");
	}
	product getresult()
	{
		return *m_product;
	}
};

class  conbuild2:public builder
{
private:
	product *m_product;
public:
	conbuild2()
	{
		m_product = new product();
	}
	void head()
	{
		m_product->add("2的头");
	}
	void body()
	{
		m_product->add("2的身体");
	}
	void leg()
	{
		m_product->add("2的腿");
	}
	void hand()
	{
		m_product->add("2的手");
	}
	product getresult()
	{
		return *m_product;
	}
};

class director
{
public:
	void createpeople(builder *s)
	{
		s->body();
		s->hand();
		s->leg();
		s->head();
	}
};

int main()
{
	director s;
	builder *p1 = new conbuild1;
	builder*p2 = new conbuild2;
	s.createpeople(p1);
	product s1 = p1->getresult();
	s1.show();
	cout<<"---------------"<<endl;
	s.createpeople(p2);
	product s2 = p2->getresult();
	s2.show();
}
相关推荐
m0_748233361 小时前
后端接口返回文件流,前端下载(java+vue)
java·前端·vue.js
刘Java1 小时前
Dubbo 3.x源码(26)—Dubbo服务引用源码(9)应用级服务发现订阅refreshServiceDiscoveryInvoker
java·dubbo·dubbo源码
蟾宫曲1 小时前
网络编程 03:端口的定义、分类,端口映射,通过 Java 实现了 IP 和端口的信息获取
java·网络·网络编程·ip·端口
魔道不误砍柴功1 小时前
Java 中 wait 和 sleep 的区别:从原理到实践全解析
java·开发语言
越甲八千2 小时前
重拾设计模式--状态模式
c++·设计模式
00Allen002 小时前
常见八股文03
java·安全·系统安全
不想被吃掉氩2 小时前
linux-多线程
java·linux·运维·c++
taiguolaotu2 小时前
java 根据路径下载文件转换为MultipartFile,并且上传到服务器
java·服务器·开发语言
龙少95432 小时前
【Http,Netty,Socket,WebSocket的应用场景和区别】
java·后端·websocket·网络协议·http
计算机学姐3 小时前
基于SpringBoot的校园求职招聘管理系统
java·前端·vue.js·spring boot·后端·mysql·intellij-idea