写点什么

代码开发篇之设计模式

作者:邱学喆
  • 2022 年 10 月 07 日
    广东
  • 本文字数:4212 字

    阅读完需:约 14 分钟

代码开发篇之设计模式

一. 概述

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。

作者刘伟出的专栏《史上最全设计模式导学》,是通俗易懂的文章,值得推荐。这篇文章是对其系列文章进行做笔记,便于后续翻阅查看。

二. 设计原则

  • 单一职责原则——一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。

  • 开闭原则——一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

  • 里氏代换原则——所有引用基类(父类)的地方必须能透明地使用其子类的对象。(多态

  • 依赖倒转原则——抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。

  • 接口隔离原则——使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

  • 合成复用原则——尽量使用对象组合,而不是继承来达到复用的目的。

  • 迪米特法则——一个软件实体应当尽可能少地与其他实体发生相互作用。

三. 创建型模式

创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。

由于创建型模式的相对于比较简单。这里只摘抄刘伟作者的对其的定义。

3.1 简单工厂模式

简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。

3.2 工厂方法模式

工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。

3.3 抽象工厂模式

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为 Kit 模式,它是一种对象创建型模式。

3.4 单例模式

单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。

3.5 原型模式

原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建型模式。

3.6 建造者模式

建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。

四. 结构型模式

结构型模式(Structural Pattern)描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。

结构型模式可以分为类结构型模式和对象结构型模式。

  • 类结构型模式中一般只存在继承关系和实现关系

  • 对象结构型模式关心类与对象的组合,通过关联关系使得在一 个类中定义另一个类的实例对象,然后通过该对象调用其方法

4.1 适配器模式

适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

4.2 桥接模式

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

4.3 组合模式

组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。

4.4 装饰模式

装饰模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。

4.5 外观模式

外观模式(Facade Pattern):为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

4.6 享元模式

享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。


这个基本是与工厂模式一起共用实现;这里不再阐述;

4.7 代理模式

代理模式(Proxy Pattern):给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

五. 行为型模式

行为型模式(Behavioral Pattern)是对在不同的对象之间划分责任和算法的抽象化。

行为型模式分为类行为型模式和对象行为型模式两种:

  • 类行为型模式:类的行为型模式使用继承关系在几个类之间分配行为,类行为型模式主要通过多态等方式来分配父类与子类的职责。

  • 对象行为型模式:对象的行为型模式则使用对象的聚合关联关系来分配行为,对象行为型模式主要是通过对象关联等方式来分配两个或多个类的职责。根据“合成复用原则”,系统中要尽量使用关联关系来取代继承关系,因此大部分行为型设计模式都属于对象行为型设计模式。

5.1 职责链模式

职责链模式(Chain of Responsibility  Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。


5.2 命令模式

命令模式(Command Pattern):将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。

这个模式与观察者模式的实现方式有所类似。个人理解,也只是语义上不同而已;具体类图结构可以参考观察者。

5.3 解释器模式

解释器模式(Interpreter Pattern):定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。解释器模式是一种类行为型模式。

这个模式一般用于语法解析。在设计阶段,就需要设计语法树模型,如图:

这个跟访问者模式有所类似,只是访问者模式是读取语法树,而解释器模式是生成语法树。

解释器模式会采用中介者(解释器)来协调。


5.4 迭代器模式

迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。

  • use——聚合类依赖迭代器,不是成员上的依赖,而是通过方法的返回类型来建立关系;

  • aggregate——迭代器关联聚合类。这里可以有两种方式

  • 迭代器作为聚合类的内部类,可以直接访问聚合类;

  • 聚合类作为迭代器的成员变量,间接访问聚合类;

5.5 中介者模式

中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装(协调)一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。


5.6 备忘录模式

备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为 Token。


5.7 观察者模式

观察者模式(Observer Pattern):定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。


5.8 状态模式

状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。


5.9 策略模式

策略模式(Strategy Pattern):定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。策略模式是一种对象行为型模式。


5.10 模板方法模式

模板方法模式(Template Method Pattern):定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

个人理解,模板模式的设计依赖于前期针对某一事物进行抽象分解拆分成固定的小模块,或者说小步骤;然后由其子类或者 Hook 形式来增加定制化;所以结构图形式多样,常规的实现方式是通过继承的方式,这里就不展示图了;

5.11 访问者模式

访问者模式(Visitor Pattern):提供一个作用于某对象结构中的各元素的操作表示,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式是一种对象行为型模式。


六. 总结

上面所罗列的 23 中设计模式,都是基于设计原则衍生出来的;设计原则中最关键的两个点:单一职责和开闭原则;所以,在代码设计阶段时,需要将其过程进行分析拆解出不可分割的"原子"子过程。哪些子过程是可变的,哪些是一成不变的。

在面向对象编程时,总是先需要先创建对象再使用对象,这时就需要考虑是否有必要或适合创建型模式,例如工厂模式和建造者模式,单例模式。

在结构型模式与行为型模式中的设计模式,较起真来,还真不好区分。例如桥接模式与策略模式,组合模式与职责链,命令模式与观察者模式等。

在日常开发过程中,经常使用到,或者有可能被用到的模式有如下:

  • 桥接模式

  • 组合模式

  • 装饰模式

  • 代理模式

  • 适配器模式

  • 职责链模式

  • 观察者模式

  • 策略模式

  • 状态模式

框架层面上经常使用的模式有如下:

  • 建造者模式

  • 观察者模式

  • 状态模式

  • 模板方法模式

  • 访问者模式

  • 解释器模式

  • 命令模式

  • 迭代器模式

一些较为冷门的模式,或者说很少被使用到的,有如下:

  • 享元模式

  • 备忘录模式

最后,我还想补充说的是,模式与模式之间是可以搭配使用,同时也无需记住这些模式。只需要记住前面说的几句话 :

  • 分析拆解成"原子"过程

  • 分析"原子"过程哪些是可变的,哪些是一成不变的

发布于: 刚刚阅读数: 3
用户头像

邱学喆

关注

签约作者;计算机原理的深度解读,源码分析 2018.08.26 加入

在IT领域keep Learning。要知其然,也要知其所以然。原理的爱好,源码的阅读。输出我对原理以及源码解读的理解。个人的仓库:https://gitee.com/Michael_Chan

评论

发布
暂无评论
代码开发篇之设计模式_设计模式_邱学喆_InfoQ写作社区