【设计模式学习笔记】建造者模式和原型模式案例详解(C++实现)

简介: 【设计模式学习笔记】建造者模式和原型模式案例详解(C++实现)

一、建造者模式

1. 什么是建造者模式

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

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

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

2. 建造者模式的实现

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

1. //最终产品类:汽车
2. class CarProduct
3. {
4. public:
5.  void set_shell(string shell) //建造汽车外壳
6.  {
7.    this->shell = shell;
8.  }
9.  void set_engine(string engine) //建造汽车发动机
10.   {
11.     this->engine = engine;
12.   }
13.   void set_whell(string whell) //建造汽车轮子
14.   {
15.     this->whell = whell;
16.   }
17.   //获取属性
18.   string get_shell()
19.   {
20.     return this->shell;
21.   }
22.   string get_engine()
23.   {
24.     return this->engine;
25.   }
26.   string get_whell()
27.   {
28.     return this->whell;
29.   }
30. private:
31.   string shell; //外壳
32.   string engine; //发动机
33.   string whell; //轮子
34. };

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

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

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

1. //具体的建造者:具体施工单位、具体的建造方式
2. class TruckBuilder : public Builder //卡车建造商
3. {
4. private:
5.  CarProduct* m_car;
6. public:
7.  TruckBuilder()
8.  {
9.    this->m_car = new CarProduct; 
10.   }
11.   virtual void builder_shell()
12.   {
13.     this->m_car->set_shell("卡车外壳");
14.   }
15.   virtual void builder_engine()
16.   {
17.     this->m_car->set_engine("卡车发动机");
18.   }
19.   virtual void builder_whell()
20.   {
21.     this->m_car->set_whell("卡车轮子");
22.   }
23.   virtual CarProduct* get_car()
24.   {
25.     return this->m_car;
26.   }
27. };
28. class TrainBuilder : public Builder //火车建造商
29. {
30. private:
31.   CarProduct* m_car;
32. public:
33.   TrainBuilder()
34.   {
35.     this->m_car = new CarProduct;
36.   }
37.   virtual void builder_shell()
38.   {
39.     this->m_car->set_shell("火车外壳");
40.   }
41.   virtual void builder_engine()
42.   {
43.     this->m_car->set_engine("火车发动机");
44.   }
45.   virtual void builder_whell()
46.   {
47.     this->m_car->set_whell("火车轮子");
48.   }
49.   virtual CarProduct* get_car()
50.   {
51.     return this->m_car;
52.   }
53. };

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

1. //指挥者:设计师,负责设计建造逻辑
2. class Director
3. {
4. public:
5.  Director(Builder* builder)
6.  {
7.    this->m_builder = builder;
8.  }
9.  //建造逻辑
10.   void builder_logic()
11.   {
12.     //1.先建造车的外壳
13.     this->m_builder->builder_shell();
14.     cout << "先建造车的外壳\t";
15.     //2.再安装发动机
16.     this->m_builder->builder_engine();
17.     cout << "再安装发动机\t";
18.     //3.最后安装车轮
19.     this->m_builder->builder_whell();
20.     cout << "最后安装车轮\n";
21.   }
22. private:
23.   Builder* m_builder;
24. };

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

1. int main()
2. {
3.  CarProduct* myCar = NULL;
4.  Builder* tempBuilder = NULL;
5.  Director* carDector = NULL;
6. 
7.  //需求:建造一辆卡车
8.  //首先找一个卡车建造商
9.  tempBuilder = new TruckBuilder;
10.   //把建造商交给指挥者(设计师)管理
11.   carDector = new Director(tempBuilder);
12.   //开始建造
13.   carDector->builder_logic();
14.   //获取产品  对象的建造逻辑和产品的表示分离
15.   myCar = tempBuilder->get_car();
16.   cout << "======产品信息======" << endl;
17.   cout << myCar->get_shell() << endl;
18.   cout << myCar->get_engine() << endl;
19.   cout << myCar->get_whell() << endl;
20.   cout << "====================" << endl;
21.   delete myCar;
22.   delete carDector;
23.   delete tempBuilder;
24. }

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

1. //新需求:需要一辆火车
2.  tempBuilder = new TrainBuilder;
3.  carDector = new Director(tempBuilder);
4.  carDector->builder_logic();
5.  myCar = tempBuilder->get_car();
6.  cout << "======产品信息======" << endl;
7.  cout << myCar->get_shell() << endl;
8.  cout << myCar->get_engine() << endl;
9.  cout << myCar->get_whell() << endl;
10.   cout << "====================" << endl;
11.   delete myCar;
12.   delete carDector;
13.   delete tempBuilder;

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

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

二、原型模式

1. 什么是原型模式

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

2. 原型模式的实现

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

1. #include <iostream>
2. using namespace std;
3. 
4. #include <String>
5. 
6. class MyString
7. {
8. public:
9.  virtual MyString* Clone() = 0;
10.   virtual void print_str() = 0;
11. };
12. 
13. class Hello : public MyString
14. {
15. private:
16.   int len;
17.   string str;
18. public:
19.   Hello()
20.   {
21.     this->len = 5;
22.     this->str = "Hello";
23.   }
24.   virtual MyString* Clone()
25.   {
26.     Hello* temp = new Hello;
27.     *temp = *this;
28.     return temp;
29.   }
30.   virtual void print_str()
31.   {
32.     cout << "len:" << len << "   str:" << str << endl;
33.   }
34. };
35. 
36. int main()
37. {
38.   MyString* h1 = new Hello;
39.   h1->print_str();
40.   MyString* h2 = h1->Clone();
41.   h2->print_str();
42. 
43.   delete h1;
44.   delete h2;
45. 
46.   system("pause");
47.   return 0;
48. }

三、创建型设计模式总结

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

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

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


相关文章
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
3月前
|
设计模式 算法
设计模式--建造者模式 builder
这篇文章通过一个电脑购买的例子,详细解释了建造者模式的四个角色(产品类、抽象构建者、实体构建类和指导者类),并提供了相应的代码实现,阐述了建造者模式在设计复杂对象时的应用和优势。
设计模式--建造者模式 builder
|
2天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
1月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
33 2
|
3月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
|
3月前
|
编译器 C++
【C++核心】指针和引用案例详解
这篇文章详细讲解了C++中指针和引用的概念、使用场景和操作技巧,包括指针的定义、指针与数组、指针与函数的关系,以及引用的基本使用、注意事项和作为函数参数和返回值的用法。
57 3
|
3月前
|
C++
【C++案例】一个项目掌握C++基础-通讯录管理系统
这篇文章通过一个通讯录管理系统的C++项目案例,详细介绍了如何使用C++实现添加、显示、删除、查找、修改和清空联系人等功能。
57 3
|
2月前
|
设计模式 JavaScript Scala
Kotlin学习笔记 - 改良设计模式 - 责任链模式
Kotlin学习笔记 - 改良设计模式 - 责任链模式
47 0
|
2月前
|
设计模式 Java Kotlin
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
32 0