设计模式 | 建造者模式和原型模式

举报
mindtechnist 发表于 2023/05/11 14:32:11 2023/05/11
【摘要】 目录一、建造者模式1. 什么是建造者模式2. 建造者模式的实现3. 建造者模式和工厂模式对比二、原型模式1. 什么是原型模式 2. 原型模式的实现 三、创建型设计模式总结一、建造者模式1. 什么是建造者模式Bulider Pattern,建造者模式,也叫做生成器模式,是一种对象创建型模式。建造者模式用于创建具有多个部件的复合对象,并隐藏了复合对象的创建过程,不同的部件建造者(Builder生...

目录

一、建造者模式

1. 什么是建造者模式

2. 建造者模式的实现

3. 建造者模式和工厂模式对比

二、原型模式

1. 什么是原型模式

 2. 原型模式的实现

 三、创建型设计模式总结


一、建造者模式

1. 什么是建造者模式

Bulider Pattern,建造者模式,也叫做生成器模式,是一种对象创建型模式。建造者模式用于创建具有多个部件的复合对象,并隐藏了复合对象的创建过程,不同的部件建造者(Builder生成器)有不同的建造方法。通过建造者模式实现了对象的构建和对象的表示的分离,也就是说,通过同样的构建过程(建造逻辑)可以创建出不同的表示(使用不同的建造者产生不同的建造方式)。

建造者模式中的4种角色:

  1. 抽象建造者角色Builder:为建造各个组件提供统一的抽象接口;
  2. 具体建造者角色ConcreteBuilder:实现抽象建造者提供的抽象接口,定义各个组件的建造方法,是组件建造的具体实施者;
  3. 指挥者Director:调用具体建造者来建造产品的各个组件,指挥者并不知道产品的具体信息,指挥者只负责规定并保证各个组件的建造过程和建造逻辑(指挥建造的过程,比如先装发动机再装轮子);
  4. 产品角色Product:被建造的复杂对象,包含组合对象的各个部件;

2. 建造者模式的实现

首先我们定义一个汽车产品类,这个汽车包含外壳、发动机、车轮三个部件,并且汽车产品类中应该包含设置各个部件和获取各个部件的方法。汽车产品类是我们最终要建造的目标,是客户的需求。

//最终产品类:汽车
class CarProduct
{
public:
	void set_shell(string shell) //建造汽车外壳
	{
		this->shell = shell;
	}
	void set_engine(string engine) //建造汽车发动机
	{
		this->engine = engine;
	}
	void set_whell(string whell) //建造汽车轮子
	{
		this->whell = whell;
	}
	//获取属性
	string get_shell()
	{
		return this->shell;
	}
	string get_engine()
	{
		return this->engine;
	}
	string get_whell()
	{
		return this->whell;
	}
private:
	string shell; //外壳
	string engine; //发动机
	string whell; //轮子
};

 定义一个抽象的建造者基类,类中统一了建造部件的接口和返回产品成品的方法。

//建造者基类:抽象施工单位
class Builder
{
public:
	virtual void builder_shell() = 0; //汽车外壳的建造方式接口
	virtual void builder_engine() = 0; //发动机的建造方式
	virtual void builder_whell() = 0; //车轮的建造方式
	virtual CarProduct* get_car() = 0; //返回建造好的汽车产品
};

定义具体建造者类,具体建造者类是产品部件的具体建造者,也就是汽车的生产商,我们定义两个汽车生产商,一个厂家生产卡车,一个厂家生产火车。

//具体的建造者:具体施工单位、具体的建造方式
class TruckBuilder : public Builder //卡车建造商
{
private:
	CarProduct* m_car;
public:
	TruckBuilder()
	{
		this->m_car = new CarProduct; 
	}
	virtual void builder_shell()
	{
		this->m_car->set_shell("卡车外壳");
	}
	virtual void builder_engine()
	{
		this->m_car->set_engine("卡车发动机");
	}
	virtual void builder_whell()
	{
		this->m_car->set_whell("卡车轮子");
	}
	virtual CarProduct* get_car()
	{
		return this->m_car;
	}
};
class TrainBuilder : public Builder //火车建造商
{
private:
	CarProduct* m_car;
public:
	TrainBuilder()
	{
		this->m_car = new CarProduct;
	}
	virtual void builder_shell()
	{
		this->m_car->set_shell("火车外壳");
	}
	virtual void builder_engine()
	{
		this->m_car->set_engine("火车发动机");
	}
	virtual void builder_whell()
	{
		this->m_car->set_whell("火车轮子");
	}
	virtual CarProduct* get_car()
	{
		return this->m_car;
	}
};

最后,应该定义一个指挥者,指挥者是汽车的设计师,它负责规划建造汽车的逻辑步骤,指挥汽车厂家(具体建造者)干活,而具体的工作有汽车厂家去干,所以指挥者不关心汽车的具体细节,只负责设计建造汽车各个部件的逻辑关系,比如先制造汽车外壳,然后安装发动机,最后安装车轮。

//指挥者:设计师,负责设计建造逻辑
class Director
{
public:
	Director(Builder* builder)
	{
		this->m_builder = builder;
	}
	//建造逻辑
	void builder_logic()
	{
		//1.先建造车的外壳
		this->m_builder->builder_shell();
		cout << "先建造车的外壳\t";
		//2.再安装发动机
		this->m_builder->builder_engine();
		cout << "再安装发动机\t";
		//3.最后安装车轮
		this->m_builder->builder_whell();
		cout << "最后安装车轮\n";
	}
private:
	Builder* m_builder;
};

最后是根据客户需求去建造汽车,假设客户需要一辆卡车。

int main()
{
	CarProduct* myCar = NULL;
	Builder* tempBuilder = NULL;
	Director* carDector = NULL;

	//需求:建造一辆卡车
	//首先找一个卡车建造商
	tempBuilder = new TruckBuilder;
	//把建造商交给指挥者(设计师)管理
	carDector = new Director(tempBuilder);
	//开始建造
	carDector->builder_logic();
	//获取产品  对象的建造逻辑和产品的表示分离
	myCar = tempBuilder->get_car();
	cout << "======产品信息======" << endl;
	cout << myCar->get_shell() << endl;
	cout << myCar->get_engine() << endl;
	cout << myCar->get_whell() << endl;
	cout << "====================" << endl;
	delete myCar;
	delete carDector;
	delete tempBuilder;
}

 假如客户提出新需求,需要一辆火车,那么我们直接让指挥者去指挥火车厂商生产即可。

    //新需求:需要一辆火车
	tempBuilder = new TrainBuilder;
	carDector = new Director(tempBuilder);
	carDector->builder_logic();
	myCar = tempBuilder->get_car();
	cout << "======产品信息======" << endl;
	cout << myCar->get_shell() << endl;
	cout << myCar->get_engine() << endl;
	cout << myCar->get_whell() << endl;
	cout << "====================" << endl;
	delete myCar;
	delete carDector;
	delete tempBuilder;

3. 建造者模式和工厂模式对比

建造者模式和工厂模式的区别是:工厂模式强调的是结果,不考虑对象的建造过程,只关注产生一个客户所需要的结果。比如,客户需要一辆大众汽车,那么就直接使用大众汽车工厂来生产一辆大众汽车,只关注大众汽车这个结果,不关心汽车外壳、发动机、轮子等部件的建造过程。建造者模式强调的是建造过程,要关注每一个部件的建造方式,以及各个部件的建造逻辑,最终组合出需要的对象。

二、原型模式

1. 什么是原型模式

Prototype Pattern,原型模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例,所以称之为Clone,被复制出来的对象具有和原型一摸一样的数据,并且在通过Clone创造另一个一模一样的对象时,不需要知道创造的过程。根据对象克隆深度层次的不同,有浅度克隆与深度克隆。

 2. 原型模式的实现

既然原型模式是复制一个一模一样的对象,那么就一定要注意潜在的深拷贝浅拷贝问题。

#include <iostream>
using namespace std;

#include <String>

class MyString
{
public:
	virtual MyString* Clone() = 0;
	virtual void print_str() = 0;
};

class Hello : public MyString
{
private:
	int len;
	string str;
public:
	Hello()
	{
		this->len = 5;
		this->str = "Hello";
	}
	virtual MyString* Clone()
	{
		Hello* temp = new Hello;
		*temp = *this;
		return temp;
	}
	virtual void print_str()
	{
		cout << "len:" << len << "   str:" << str << endl;
	}
};

int main()
{
	MyString* h1 = new Hello;
	h1->print_str();
	MyString* h2 = h1->Clone();
	h2->print_str();

	delete h1;
	delete h2;

	system("pause");
	return 0;
}

 三、创建型设计模式总结

顾名思义,创建型设计模式就是处理对象创建过程的设计模式。创建型模式主要是将系统所需要的用到的具体类封装起来,在内部实现这些具体类的创建和结合,并对外隐藏这个过程细节。创建型设计模式主要包括:

  • 单例模式
  • 简单工厂模式
  • 工厂模式
  • 抽象工厂模式
  • 建造者模式
  • 原型模式

其中,简单工厂模式因为不符合开闭原则,它不属于标准的23种设计模式。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。