【设计模式学习笔记】建造者模式和原型模式案例详解(C++实现)
目录
一、建造者模式
1. 什么是建造者模式
Bulider Pattern,建造者模式,也叫做生成器模式,是一种对象创建型模式。建造者模式用于创建具有多个部件的复合对象,并隐藏了复合对象的创建过程,不同的部件建造者(Builder生成器)有不同的建造方法。通过建造者模式实现了对象的构建和对象的表示的分离,也就是说,通过同样的构建过程(建造逻辑)可以创建出不同的表示(使用不同的建造者产生不同的建造方式)。
建造者模式中的4种角色:
- 抽象建造者角色Builder:为建造各个组件提供统一的抽象接口;
- 具体建造者角色ConcreteBuilder:实现抽象建造者提供的抽象接口,定义各个组件的建造方法,是组件建造的具体实施者;
- 指挥者Director:调用具体建造者来建造产品的各个组件,指挥者并不知道产品的具体信息,指挥者只负责规定并保证各个组件的建造过程和建造逻辑(指挥建造的过程,比如先装发动机再装轮子);
- 产品角色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种设计模式。