「设计模式」- 总览

247 阅读10分钟

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

前言

计划是每个设计模式都要有详解的一期文章,或者几个设计模式一起写一期;但是这么多设计模式,总要有个导航;本文对24种设计模式进行一个分类导航,并对其做一个概述。

这样做的目的是,如果你已经掌握这个设计模式,那么可以直接跳过,或者看个概述就能复习一遍,而尚未掌握的设计模式可以直接查看详解的文章

目前详解文章的完成进度:>>===================⚡Loading⚡ 4.16%

已完成:单例模式代理模式简单工厂、抽象工厂、工厂方法


1. 软件设计的七大原则

1.1 开闭原则

定义:一个软件实体如类、模块函数应该对扩展开放,对修改关闭

对于开闭原则,强调的是用抽象构建框架,用实现扩展细节;例如我们Java中常用的extends 关键字,通过继承基类,来达到扩展功能的目的。

1.2 依赖倒置原则

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。即针对接口编程,不要针对实现编程。

每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块(一般是接口,抽象类),原子逻辑的组装就是高层模块;例如我们写Controller时,通过调用Service 层,来实现具体逻辑的调用

1.3 单一职责

定义:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中

该原则提出对象不应该承担太多职责,如果一个对象承担了太多的职责,至少存在以下两个缺点:
一个职责的变化可能会影响、削弱或者抑制这个类实现其他职责的能力。

当客户端需要该对象的某一个职责时,不得不将其他不需要的职责全都包含进来,从而造成冗余代码或代码的浪费

典型的设计就是SpringMVC 中的分层设计,将不同职责的类进行分层。

1.4 里氏替换原则

定义:所有引用基类(父类)的地方必须能透明地使用其子类的对象。即子类能够必须能够替换基类能够从出现的地方。子类也能在基类 的基础上新增行为。

举例的话,有著名的“正方形不是长方形”。

1.5 接口隔离法则

定义:用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口

  • 一个类对一个类的依赖应该建立在最小的接口上
  • 建立单一接口,不要建立庞大臃肿的接口
  • 尽量细化接口,接口中的方法尽量少
  • 注意适度原则,一定要适度
  • 接口隔离法则符合我们常说的高内聚低耦合的设计思想,从而使得类具有很好的可读性、可扩展性和可维护性。

比如我们创建了一个接口叫动物,有吃、飞、游泳的接口方法,那么一只鸟继承这个动物接口时就被迫实现了游泳方法

1.6 迪米特原则

定义:一个对象对其他对象保持最少的了解,尽量降低类与类之间的耦合,强调只与相关类交流。相关类指的是出现在成员变量、方法的输入、输出参数中的类

例如,老师需要班长统计班级学生的年龄,老师不需要关心学生的类型,这一切由班长来负责

1.7 合成复用原则

定义:尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的

通常类的复用分为继承复用和合成复用两种,继承复用虽然有简单和易实现的优点,但它也存在以下缺点:

  1. 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。
  2. 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展与维护。
  3. 它限制了复用的灵活性。从父类继承而来的实现是静态的,在编译时已经定义,所以在运行时不可能发生变化。

采用组合或聚合复用时,可以将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,它有以下优点:

  1. 它维持了类的封装性。因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。
  2. 新旧类之间的耦合度低。这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。
  3. 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成员对象类型相同的对象。

2. 创建型设计模式 - 6种

创建型设计模式的主要关注点是“怎么创建对象”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。

2.1 创建型 - 单例模式(Singleton pattern)

详解:「设计模式」- 教你手写单例模式

定义:确保一个类只有一个实例,并提供该实例的全局访问点。

单例模式有以下3个特点:

  1. 单例类只有一个对象
  2. 该单例对象必须由单例类自行创建
  3. 单例类对外提供一个访问该单例的全局访问点

2.2 创建型 - 简单工厂(Simple Factory)

详解:「设计模式」- 浅谈工厂模式

定义:把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化,这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。

在简单工厂模式中用于被创建实例的方法通常为静态方法,因此简单工厂模式又被成为静态工厂方法

2.3 创建型 - 工厂方法(Factory Method)

详解:「设计模式」- 浅谈工厂模式

定义:它定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。

2.4 创建型 - 抽象工厂(Abstract Factory)

详解:「设计模式」- 浅谈工厂模式

定义:抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。

2.5 创建型 - 生成器(Builder)

定义:封装一个对象的构造过程,并允许按步骤构造

2.6 创建型 - 原型模式(Prototype)

定义:使用原型实例指定要创建对象的类型,通过复制这个原型来创建新对象。


3. 结构型设计模式 - 7种

结构型设计模式主要关注如何将现有类或对象组织在一起形成更加强大的结构

分为两种:

  1. 类结构型模式:关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系
  2. 对象结构型模式:关心类与对象的组合,通过关联关系使得在一个类中定义另一个类的实例对象,然后通过该对象调用其方法。更符合“合成复用原则”

3.1 结构型 - 外观(Facade)

定义:为子系统的一组接口提供一个统一的入口。外观模式定义了一个高层接口使得能更方便地使用子系统。

3.2 结构型 - 适配器(Adapter)

定义:将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作。

3.3 结构型 - 桥接(Bridge)

定义:将抽象部分与它的实现部分解耦,使它们都能独立地变化

3.4 结构型 - 组合(Composite)

定义:组合多个对象形成树形结构以表示"部分——整体"的层次结构。组合模式使客户能统一对待单个对象(即叶子对象)和组合对象(即容器对象)

3.5 结构型 - 装饰者(Decorator)

定义:动态地给一个对象添加职责。相较于继承,装饰模式则提供了一种更为灵活的方式来扩展功能。

3.6 结构型 - 享元(Flyweight)

定义:利用共享的方式来支持大量细粒度的对象,这些对象一部分内部状态是相同的。 它让某个类的一个实例能用来提供许多"虚拟实例"。

3.7 结构型 - 代理(Proxy)

详细文章:「设计模式」- 聊一聊代理模式 (juejin.cn)

定义:为另一个对象提供一个替身或占位符以控制对这个对象的访问。


4. 行为型设计模式 - 11种

行为型的设计模式主要关注系统中对象之间的相互交互,研究系统在运行时对象之间的相互通信和协作,进一步明确对象的职责。

4.1 行为型 - 责任链(Chain Of Responsibility)

定义:通过责任链模式, 你可以为某个请求创建一个对象链. 每个对象依序检查此请求并对其进行处理或者将它传给链中的下一个对象。

4.2 行为型 - 策略(Strategy)

定义:定义了算法族, 分别封闭起来, 让它们之间可以互相替换, 此模式让算法的变化独立于使用算法的客户

4.3 行为型 - 模板方法(Template Method)

定义:在一个方法中定义一个算法的骨架, 而将一些步骤延迟到子类中. 模板方法使得子类可以在不改变算法结构的情况下, 重新定义算法中的某些步骤

4.4 行为型 - 命令模式(Command)

定义:将"请求"封闭成对象, 以便使用不同的请求,队列或者日志来参数化其他对象. 命令模式也支持可撤销的操作

4.5 行为型 - 观察者(Observer)

定义:在对象之间定义一对多的依赖, 这样一来, 当一个对象改变状态, 依赖它的对象都会收到通知, 并自动更新

4.6 行为型 - 访问者(Visitor)

定义:当你想要为一个对象的组合增加新的能力, 且封装并不重要时, 就使用访问者模式

4.7 行为型 - 状态(State)

定义:允许对象在内部状态改变时改变它的行为, 对象看起来好象改了它的类

4.8 行为型 - 解释器(Interpreter)

定义:使用解释器模式为语言创建解释器,通常由语言的语法和语法分析来定义

4.9 行为型 - 迭代器(Iterator)

定义:提供一种方法顺序访问一个聚合对象中的各个元素, 而又不暴露其内部的表示

4.10 行为型 - 中介者(Mediator)

定义:使用中介者模式来集中相关对象之间复杂的沟通和控制方式

4.11 行为型 - 备忘录(Memento)

定义:当你需要让对象返回之前的状态时(例如, 你的用户请求"撤销"), 你使用备忘录模式