设计模式(英语 design pattern)是对面向对象设计中反复出现的问题的解决方案。这个术语是在1990年代由Erich Gamma等人从建筑设计领域引入到计算机科学中来的。这个术语的含义还存有争议。算法不是设计模式,因为算法致力于解决问题而非设计问题。设计模式通常描述了一组相互紧密作用的类与对象。设计模式提供一种讨论软件设计的公共语言,使得熟练设计者的设计经验可以被初学者和其他设计者掌握。设计模式还为软件重构提供了目标。
随着软件开发社群对设计模式的兴趣日益增长,已经出版了一些相关的专著,定期召开相应的研讨会,而且Ward Cunningham为此发明了WikiWiki用来交流设计模式的经验。
转载:百度百科:软件设计模式_百度百科 (baidu.com)
1 原则
1.1 开闭原则
开闭原则是对扩展开放,对修改关闭。增加功能是通过增加代码来实现的,而不是去修改源代码。
写一个抽象的计算器类,即接口,定义相应的方法,将方法定义成纯虚函数,以便子类继承时实现。当我们需要加法时,定义加法类继承抽象的计算器类,再实现接口里面的方法。当加入其他功能时,再写个类继承抽象类即可,以此类推。
详见:【设计模式】开闭原则_StudyWinter的博客-CSDN博客
1.2 迪米特原则
迪米特原则,也称为最少知识原则。如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
设想这样一个案例,假如要买房,目前有A、B两套房,分别是高品质和低品质,购房者直接和这两套房打交道,购买符合自己意愿的房。
使用迪米特原则来处理这个问题,也就是客户可以直接找“中介”,告诉“中介”自己需要什么类型的房,”中介“去和具体的房打交道,这就减少了客户端和房源的具体交接。
详见:【设计模式】迪米特原则_StudyWinter的博客-CSDN博客
1.3 合成复用原则
合成复用原则是指:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
详见:【设计模式】合成复用原则_StudyWinter的博客-CSDN博客
1.4 依赖倒转原则
依赖倒转原则又称依赖倒置原则:抽象不应该依赖细节,细节应该依赖于抽象。说白了,就是针对接口编程,不要针对实现编程。
依赖倒置原则包含三层含义:
(1)高层模块不应该依赖低层模块,两者都应该依赖其抽象;
(2)抽象不应该依赖细节;
(3)细节应该依赖抽象。
详见:https://blog.csdn.net/Zhouzi_heng/article/details/116208491
2 几种工厂模式
让工厂创建对象。传入参数,让工厂知道应该创建什么类型的对象。
优点:
(1)客户端和具体实现解耦;
(2)对于某些对象创建复杂的情况,不用考虑这些了。
2.1 简单工厂模式
主要优点:
- 结构简单,调用方便。工厂和产品的职责区分明确;
- 客户端无需知道所创建具体产品的类名,只需知道参数即可。
主要缺点:
- 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则,违背开闭原则。
应用场景:
- 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂;
- 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
详见:【设计模式】简单工厂模式_StudyWinter的博客-CSDN博客
2.2 工厂方法模式
之前提到了简单工厂模式
其主要缺点:
(1)简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响;
(2)工厂类代码会非常臃肿,违背高聚合原则,违背开闭原则。
那么如果实现开闭原则呢?把工厂也抽象处理。
【工厂方法模式 = 简单工厂模式 + 开闭原则】
优点:
(1)不需要记住具体类名,甚至连具体参数都不用记忆;
(2)实现了对象创建和使用的分离;
(3)系统的可扩展性也就变得非常好,无需修改接口和原类。
缺点:
(1)增加系统中类的个数,复杂度和理解度增加;
(2)增加了系统的抽象性和理解难度。
应用场景:
(1)客户端不知道它所需要的对象的类。
(2)抽象工厂类通过其子类来指定创建哪个对象。
详见:
【设计模式】工厂方法模式_StudyWinter的博客-CSDN博客
2.3 抽象工厂模式
对工厂方法模式继续抽象
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
产品族:一个品牌下面的所有产品;例如A地的苹果、香蕉、鸭梨。
产品等级:多个品牌下面的同种产品;例如A地、B地、C地的苹果。
详见:【设计模式】抽象工厂模式_StudyWinter的博客-CSDN博客
3 设计模型
3.1 单例模式
概念:单例模式是一种常用的软件设计模式。它的核心结构只包含一个被称为单例的特殊类。它的目的是保证一个类仅有一个实例。
应用场景:有一些对象只需要一个,如:一台PC连接一个键盘、任务管理器只能打开一个。
其构建步骤:
(1)把构造函数私有化;
(2)增加静态的、私有的、类的指针变量;
(3)提供静态的对外接口,可以让用户获得单例对象。
class A
{
private:
// 1、把构造函数私有化
A()
{
a = new A;
}
private:
// 2、增加静态的、私有的 类的指针变量
static A* a;
public:
// 3、提供静态的对外接口,可以让用户获得单例对象
static A* getInstance()
{
return a;
}
};
//静态属性,类外初始化
A* A::a = NULL;
int main(int argc, char** argv) {
A::getInstance();
return 0;
}
赖汉式
class Singleton_lazy
{
private:
Singleton_lazy()
{
}
public:
static Singleton_lazy* getInstance()
{
if (pSingle == NULL)
{
pSingle = new Singleton_lazy;
}
return pSingle;
}
private:
static Singleton_lazy* pSingle;
};
// 静态成员类外初始化
Singleton_lazy* Singleton_lazy::pSingle = NULL;
饿汉式
class Singleton_lazy
{
private:
Singleton_lazy()
{
}
public:
static Singleton_lazy* getInstance()
{
return pSingle;
}
private:
static Singleton_lazy* pSingle;
};
// 静态成员类外初始化
Singleton_lazy* Singleton_lazy::pSingle = new Singleton_lazy;
详见:【设计模式】01 单例模式_StudyWinter的博客-CSDN博客
3.2 代理模式
代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
具体实现上:原来的类和代理类需要实现同一个接口(共同继承某个类)
详见:【设计模式】02 代理模式_StudyWinter的博客-CSDN博客
3.3 外观模式
外观模式为一组功能类似的类群,比如类库、子系统等,提供一个简单的界面,这个一致的界面被称作外观模式。
详见:【设计模式】03 外观模式_StudyWinter的博客-CSDN博客
3.4 适配器模式
适配器模式 就是将已经写好的接口(但是这个接口不符合要求),转换成目标接口
详见:【设计模式】04 适配器模式_StudyWinter的博客-CSDN博客
3.5 模版方法模式
模板方法模式(Template Method Pattern):定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
简单来说,当你频繁地需要执行某些操作,这其中的操作有共性,也有差异性的地方,我们可以用模板方法把共性的操作抽取出来,即定义一个操作中算法的“框架”,把差异性的步骤延迟到子类中,即让子类来实现差异化的步骤。
详见:https://blog.csdn.net/Zhouzi_heng/article/details/116426402
3.6 策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
具体实现时:有抽象策略、具体策略
详见:【设计模式】06 策略模式_StudyWinter的博客-CSDN博客
3.7 命令模式
命令模式:将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
命令模式可以将请求发送者和接收者完全解耦,,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求。而不必知道如何完成请求。
详见:【设计模式】07 命令模式_StudyWinter的博客-CSDN博客
3.8 观察者模式
观察者模式的动机:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式解决什么问题:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
详见:【设计模式】08 观察者模式_StudyWinter的博客-CSDN博客
3.9 装饰器模式
装饰器模式(Decorator Pattern),也叫包装模式 Wrapper Pattern
是指在不改变原有对象的基础之上,将功能附加到对象上.提供了比继承更灵活的替代方法 属于结构型模式
详见:【设计模式】09 装饰器模式_StudyWinter的博客-CSDN博客
未完待续......