设计 模式
文章目录
- 常见的23种设计模式:创建型模式、结构型模式、行为型模式
- 一、创建型模式
- 1.单例模式:Singleton
- (1)单例对象的自动释放(自动delete单例对象)的4种方式
- ①atexit( ) + 饿汉模式
- ②友元类
- ③内部类+private+static静态数据成员
- ④pthread_once( )
- 2.抽象工厂模式
- 3.建造者模式
- 4.工厂模式
- (1)简单工厂
- (2)工厂方法
- (3)抽象工厂
- 5.原型模式
- 二、结构型模式
- 1.适配器模式
- 2.桥接模式
- 3.装饰模式
- 4.组合模式
- 5.外观模式
- 6.享元模式
- 7.代理模式 Proxy
- 三、行为型模式
- 1.模板方法模式
- 2.命令模式
- 3.迭代器模式
- 4.观察者模式
- 5.中介者模式
- 6.备忘录模式
- 7.解释器模式 (Interpreter模式)
- 8.状态模式
- 9.策略模式
- 10.职责链模式 (责任链模式)
- 11.访问者模式
- 四、其他非23种经典模式的设计模式
- 1. 编译防火墙 Pimpl
- (1)Line.h
- (2)Line.cc
- (3)testLine.cc
- 2.Reactor模式
- 3.Proactor模式
常见的23种设计模式:创建型模式、结构型模式、行为型模式
设计模式:它是解决特定问题的一系列套路,有一定的普遍性。它可以提高代码的可重用性、可读性、可靠性、可扩展性。
一、创建型模式
创建型模式 (Creational patterns) 有5种
提供对象创建机制,增加现有代码的灵活性和重用。
1.单例模式:Singleton
单例模式Singleton(只能创建一个对象)
#include <iostream>using std::cout;
using std::endl;//设计需求:一个类只能创建一个对象
//适用场景:全局唯一的资源、对象、变量都可以使用单例模式class Singleton
{
public:static Singleton *getInstance(){if(nullptr == _pInstance){_pInstance = new Singleton();}return _pInstance;}static void destroy(){if(_pInstance){delete _pInstance;_pInstance = nullptr;}}private:Singleton(){cout << "Singleton()" << endl;}~Singleton(){cout << "~Singleton()" << endl;}private:static Singleton *_pInstance;
};Singleton *Singleton::_pInstance = nullptr;/* Singleton gS1;//全局对象,error */
/* Singleton gS2;//全局对象,error */int main()
{/* Singleton s1;//栈, error *//* Singleton s2;//栈, error *//* Singleton *ps1 = new Singleton();//error */Singleton *ps1 = Singleton::getInstance();Singleton *ps2 = Singleton::getInstance();cout << "ps1 = " << ps1 << endl;cout << "ps2 = " << ps2 << endl;/* delete ps1;//error *//* delete ps2;//error *//* ps1->destroy(); *//* ps2->destroy(); */Singleton::destroy();Singleton::destroy();return 0;
}
(1)单例对象的自动释放(自动delete单例对象)的4种方式
①atexit( ) + 饿汉模式
②友元类
③内部类+private+static静态数据成员
④pthread_once( )
2.抽象工厂模式
3.建造者模式
4.工厂模式
(1)简单工厂
简单工厂:有一个工厂类,里面每个成员函数对应生产一种产品
1.定义
简单工厂模式(静态工厂方法模式):
①工厂会根据产品的名字生产出对应的产品。
②一个工厂可以生产出多个产品。
③简单工厂模式提供了专门的工厂类用于创建对象,实现了对象创建和使用的分离。
2.优点
只需要知道产品的名字就可以生产出对应的产品。
3.缺点
违反了设计原则:单一职责原则 (工厂的功能过于复杂)、开放闭合原则(增加新产品需要修改工厂源代码)、依赖倒置原则 (面向抽象编程,而不是面向具体编程)
4.类图
5.代码链接:https://github.com/WangEdward1027/DesignPatterns/blob/main/Factory/simpleFactory2.cpp
(2)工厂方法
工厂方法:有一个抽象工厂类,下面派生各个具体产品的工厂。每一个产品对应一个工厂,即一个工厂仅能生产一个具体的产品。
1.定义
工厂类作为抽象类,每一个产品对应一个派生类工厂。
2.优点
①满足了单一职责原则、开放闭合原则、依赖倒置原则
②新增代码时,只需要在Figure类和Factory类下分别派生梯形类,然后依赖。不需要修改源代码。
3.缺点
工厂的数量会随着产品数量的增加而增加,一对一。
对于有大量细分类型产品(产品族)的生产需求,不适合管理工厂。
4.类图
5.代码链接:https://github.com/WangEdward1027/DesignPatterns/blob/main/Factory/factoryMethod.cpp
(3)抽象工厂
抽象工厂:有一个抽象工厂类,成员函数是各个品牌。派生类是所有品牌对应的产品系列。新增一个系列很容易,但(不修改抽象工厂类的话)无法新增品牌。每个具体工厂可以生产所有品牌对应的该系列产品。每个具体工厂类负责生产一系列相关或相互依赖的产品。
1.定义
2.优点
①抽象工厂,减少了工厂的数量。
②可以对一类品牌的产品进行细分
③每个工厂类可以生产产品族
3.缺点
不修改源代码,无法生产新类型品牌。只能在已有品牌上进行新系列产品的扩展。
4.类图
不适合新的品牌,但时候老品牌出新的产品系列。
两个品牌,下属两个产品。
抽象工厂忘了加析构函数
三个品牌,下属三个产品。
5.原型模式
二、结构型模式
结构型模式(Structural patterns)有7种
解释如何将对象和类组装成更大的结构,同时保持结构的灵活性和高效性。
1.适配器模式
做接口:适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中
2.桥接模式
3.装饰模式
4.组合模式
5.外观模式
6.享元模式
7.代理模式 Proxy
string写时复制COW,不能分开读和写,就用charProxy。
C++(week11): C++基础 第五章: 运算符重载、友元
三、行为型模式
行为型模式(Behavioral patterns)11种
负责有效的沟通和对象之间的责任分配。
1.模板方法模式
2.命令模式
3.迭代器模式
4.观察者模式
1.概念
观察者模式(Observer Pattern)是一种行为型设计模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主题对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。这个模式常用于实现事件处理系统。
2.观察者模式的结构
观察者模式涉及到四个主要角色:
(1)主题(Subject):维护观察者列表,提供方法来增加和移除观察者,并在状态发生变化时通知所有观察者。
(2)具体主题(Concrete Subject):具体的主题类,维护具体的状态,并在状态变化时通知观察者。
(3)观察者(Observer):定义了一个更新接口,用于接收主题通知。
(4)具体观察者(Concrete Observer):实现观察者接口,定义如何响应主题的更新
3.观察者模式的主要特点
(1)松耦合:主题(Subject)和观察者(Observer)之间的耦合度很低。主题只知道观察者实现了某个接口,而不知道具体的实现细节。这使得主题和观察者可以独立地扩展和修改。
(2)动态观察者列表:观察者可以在运行时动态地加入或退出,灵活性高。
(3)广播通信:主题对象状态发生变化时,会通知所有注册的观察者,实现了一种广播通信机制。
(4)支持事件驱动模型:观察者模式适合用于需要事件通知机制的系统,如GUI应用程序中的事件处理、消息系统等。
4.实现
(1)所有关注者(attach)的,在主题更新后会得到通知(notify)。观察者会被用list链表保存。若不想被通知,则可以取消关注(detach)。
(2)定义对象的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
当一个对象发生了变化,关注它的对象就会得到通知;这种交互也称为发布-订阅(publish-subscribe)。
4.类图
5.代码链接:https://github.com/WangEdward1027/DesignPatterns/blob/main/Observer/Observer.cpp
5.中介者模式
6.备忘录模式
7.解释器模式 (Interpreter模式)
8.状态模式
9.策略模式
10.职责链模式 (责任链模式)
11.访问者模式
四、其他非23种经典模式的设计模式
1. 编译防火墙 Pimpl
C++(week11): C++基础 第五章: 运算符重载、友元
(1)Line.h
#ifndef __LINE_H__
#define __LINE_H__class Line
{
public:Line(int x1, int y1, int x2, int y2);void printLine();~Line();class LinePimpl;//类前向声明
private:LinePimpl *_pimpl;
};#endif
(2)Line.cc
#include "Line.h"
#include <iostream>using std::cout;
using std::endl;class Line::LinePimpl
{
public:LinePimpl(int x1, int y1, int x2, int y2): _pt1(x1, y1), _pt2(x2, y2){cout << "LinePimpl(int, int, int, int)" << endl;}void printLinePimpl(){_pt1.print();cout << "--->";_pt2.print();cout << endl;}~LinePimpl(){cout << "~LinePimpl()" << endl;}private://内部类,嵌套类class Point{public:Point(int ix = 0, int iy = 0): _ix(ix), _iy(iy){cout << "Point(int = 0, int = 0)" << endl;}void print(){cout << "(" << this->_ix<< ", " << this->_iy<< ")";}~Point(){cout << "~Point()" << endl;}private:int _ix;int _iy;};
private:Point _pt1;//类对象成员(子对象)Point _pt2;
};Line::Line(int x1, int y1, int x2, int y2)
: _pimpl(new LinePimpl(x1, y1, x2, y2))
{cout << "Line(int, int, int, int )" << endl;
}void Line::printLine()
{_pimpl->printLinePimpl();
}Line::~Line()
{cout << "~Line()" << endl;if(_pimpl){delete _pimpl;_pimpl = nullptr;}
}
(3)testLine.cc
#include "Line.h"
#include <iostream>using std::cout;
using std::endl;int main(int argc, char **argv)
{Line line(1, 2, 3, 4);cout << "line = ";line.printLine();return 0;
}
2.Reactor模式
reactor模式,反应堆模式。是高度封装的epoll (或其他IO多路复用),事件驱动模型。
是一种设计模式, 是服务器的重要框架: 是一种事件驱动的反应堆模式, 高效的事件处理模型。
reactor模型有三个重要的组件:多路复用器、事件分发器、事件处理器
小林coding:9.3 高性能网络模式:Reactor 和 Proactor | 小林coding (xiaolincoding.com)
Reactor 模式也叫 Dispatcher
模式,即 I/O 多路复用监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程 / 线程。
3.Proactor模式
Reactor | Proactor |
---|---|
Reactor 模式是基于非阻塞式的同步I/O操作,等待事件发生并同步处理它们 | Proactor 模式是基于异步I/O操作,应用程序异步执行操作并在完成时收到通知 |
Reactor模式是“等待事情发生然后处理” | Proactor模式是“请求事情发生,事情完成了再通知我”。主动发起异步调用 |
Reactor更多关注于响应已发生的事件 | Proactor则是主动发起操作并在完成后得到通知 |
Reactor 模式 使用的是非阻塞式I/O,但在处理事件时通常表现为同步处理方式 | Proactor 模式 是基于异步I/O的,彻底采用非阻塞式操作,并通过异步方式处理完成的I/O事件 |
①阻塞式I/O:使线程在等待I/O操作完成时停止执行,可能导致性能瓶颈。
②非阻塞式I/O:允许线程在I/O操作等待期间继续执行,提高了程序的并发性能和响应性。
③异步I/O:是非阻塞式I/O的进一步发展,它允许程序完全不受I/O操作的阻塞影响,能够在I/O操作完成时接收通知。
Linux的异步I/O不完善,还需要单独配分一个线程来实现Proactor。所以一般使用Reactor。
Proactor是异步网络模式。事件完成才通知。
Reactor是非阻塞同步网络模式。事件就绪就通知。