系列总链接:https://blog.csdn.net/qq_22122811/article/details/112360387
参考:https://blog.csdn.net/jxh_123/article/details/37929843
https://www.cnblogs.com/HPAHPA/p/10285425.html
对上述链接作者表示感谢,如有侵权,望告知,立删!
一:相关问题及模式提出
各个手机品牌在生产手机的时候,都是有固定的流程的,先生产手机相机,耳机,屏幕等,由于需要做的事从结果来看是一样,先组装,最后行成手机的样式,这里将组装过程和最后的表示(组装后的手机产品)分开来,这其中用固定的流程去完成组装,就是应用了建造者模式的思想;类似的,厨师烧菜需要经过烧火,放油,放菜,炒菜,放料,炒菜。。。等过程,其实这些步骤都是类似的,但由于有些厨师粗心,可能会漏掉其中某一步,或者将顺序颠倒了,最后导致味道不太理想,像麦当劳和肯德基为什么能做到所有的门店的食品味道一致,正是因为他们将这制作过程的用料,顺序都固定了,所以就能保证味道都一样的好,这里也需要用建造者模式。下面以第一个组装手机例子来讲解建造者模式。
该设计模式初理解:
做一些事情有固定的流程,为了规范化这些流程,并且统一化,所以有了建造者模式。
二:初设计
同上所提到,先不添加设计模式,就需要添加如下类:
Phone类:手机的零配件设置,获取;
Builder类:手机零配件的组装过程;
客户端:如果是小米手机生产工人,按照流程生产出一个手机;如果是华为就一致的过程生产手机;
根据上述的思路及代码编写过程,容易发现如果步骤多了,让两个工人在客户端分别按照流程一步步去完成手机的生产,步骤少还好,步骤多的时候就会很麻烦,难免出错,但我们把流程都固定下来,有一个指挥者把流程都统一了,这样就不会出现因为流程某一步骤缺失或者顺序颠倒的问题。下面是建造者模式下的手机生产过程:
三:优化
将过程改成了建造者模式,代码过程如下:
#include <QCoreApplication>
#include <QDebug>
#include "BuilderModel.h"
#include <QDebug>
// 产品:手机
class Phone
{
public:
Phone(){
};
void setCamera(QString camera){
m_camera = camera;
};
void setScreen(QString screen){
m_screen = screen;
};
void setEarphone(QString earphone){
m_earphone = earphone;
};
void displayCamera(){
qDebug() << m_camera;
};
void displayScreen(){
qDebug() << m_screen;
};
void displayEarphone(){
qDebug() << m_earphone;
};
private:
QString m_camera;
QString m_screen;
QString m_earphone;
};
// 建造者:手机生产
class PhoneBuilder
{
public:
PhoneBuilder(){
}
virtual void buildCamera() = 0;
virtual void buildScreen() = 0;
virtual void buildEarphone() = 0;
virtual Phone* getPhone(){
return m_phone;
};
protected:
Phone* m_phone;
};
// 建造者1:小米生产工人
class XiaoMiBuilder : public PhoneBuilder
{
public:
XiaoMiBuilder(){
m_phone = new Phone();
}
void buildCamera() override{
m_phone->setCamera("XiaoMi camera");
};
void buildScreen() override{
m_phone->setScreen("XiaoMi screen");
};
void buildEarphone() override{
m_phone->setEarphone("XiaoMi earphone");
};
};
// 建造者2:华为生产工人
class HuaweiBuilder : public PhoneBuilder
{
public:
HuaweiBuilder(){
m_phone = new Phone();
}
void buildCamera() override{
m_phone->setCamera("Huawei camera");
};
void buildScreen() override{
m_phone->setScreen("Huawei screen");
};
void buildEarphone() override{
m_phone->setEarphone("Huawei earphone");
};
};
// 指挥者:装配工人
class Assembler
{
public:
void createThePhone(PhoneBuilder* phoneBlder){
phoneBlder->buildCamera();
phoneBlder->buildScreen();
phoneBlder->buildEarphone();
};
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 1.分配一个装配工人,用来完成手机的组装
Assembler* assmbler = new Assembler;
// 2.分配一个小米零配件生产工人
PhoneBuilder* xiaomibuilder = new XiaoMiBuilder;
// 3.装配工人生产小米手机,带入小米零配件生产的类
assmbler->createThePhone(xiaomibuilder);
xiaomibuilder->getPhone()->displayCamera();
xiaomibuilder->getPhone()->displayScreen();
xiaomibuilder->getPhone()->displayEarphone();
// 华为手机生产过程同小米手机的类似
PhoneBuilder* huaweiBuilder = new HuaweiBuilder;
assmbler->createThePhone(huaweiBuilder);
huaweiBuilder->getPhone()->displayCamera();
huaweiBuilder->getPhone()->displayScreen();
huaweiBuilder->getPhone()->displayEarphone();
return a.exec();
}
四:模式提出
建造者模式概念:
建造者模式基本代码:
#include "BuilderModel.h"
// 实现效果是建造者建造产品
/* 为什么要用建造者模式?
* 做一些事情有固定的流程,为了规范化这些流程,并且统一化,所以有了建造者模式。
*/
// 产品类
class Product
{
public:
QList<QString> parts;
Product(){
}
void Add(QString part){
parts.append(part);
};
void Show(){
qDebug() << "Product creat ---";
QString part;
foreach(part, parts){
qDebug() << part;
};
};
};
// 抽象建造者类
class Builder
{
public:
virtual void BuildPartA() = 0;
virtual void BuildPartB() = 0;
virtual Product* GetResult() = 0;
};
// 具体建造者类1
class ConcreteBuilder1 : public Builder
{
private:
Product* product;
public:
ConcreteBuilder1(){
product = new Product();
}
void BuildPartA() override{
product->Add("part A");
};
void BuildPartB() override{
product->Add("part B");
};
Product* GetResult() override{
return product;
};
};
// 具体建造者类2
class ConcreteBuilder2 : public Builder
{
private:
Product* product;
public:
ConcreteBuilder2(){
product = new Product();
}
void BuildPartA() override{
product->Add("part X");
};
void BuildPartB() override{
product->Add("part Y");
};
Product* GetResult() override{
return product;
};
};
// 指挥者类
class Director
{
public:
void Construct(Builder* builder){
builder->BuildPartA();
builder->BuildPartB();
};
};
// 客户端代码
BuilderModel::BuilderModel()
{
// 1.指挥者:去指挥生产产品流程的人
Director* director = new Director();
// 2.生产者:创建生产者对象,用基类指针指向
Builder* b1 = new ConcreteBuilder1();
//Builder* b2 = new ConcreteBuilder2();
// 3.指挥流程,指挥者指挥生产
director->Construct(b1);
// 4.其他:打印生产者生产产品情况
Product* p1 = b1->GetResult();
p1->Show();
}
五:优缺点及适用环境
5.1:优缺点
优点:
1.建造者独立,易扩展
缺点:
1.产品必须具有相同属性
2.产品越多,需要的建造者类也就越多
5.2:适用场景
“主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建面临着复杂的变化”。(大话设计模式)这样的情况下,就需要将对象内部构建过程固定下来,这样就能减少因为对构建过程的步骤缺失或者颠倒,最后出错的问题。
六:小结
建造者模式是在当创建复杂对象的算法应独立于该对象的组成部分以及它们的装配方法时适用的模式。简单理解,一个复杂的对象创建过程复杂,就可以将它独立出来,把对象的组成部分和装配方法都分别来,这样能减少因为创建步骤出错导致的问题。