终于有人将23种设计模式与七大设计原则整理明白了(三)!!!

简介: 这篇文章主要介绍23种设计模式以及七大设计原则

16. 命令模式


16.1 问题引入


问题引入(智能生活)


16.2命令模式介绍


命令模式介绍

  • 命令模式:在开发中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,此时我们只需在程序运行时指定具体的请求接收者即可。
  • 命令模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。
  • 在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命令),同时命令模式也支持撤销的操作

微信截图_20220609214205.png

命令模式的原理类图

微信截图_20220609214217.png

命令模式的角色及职务的分析

Invoker:是调用者角色。

Command:是命令角色,需要执行的所有命令都在这里,可以是接口或者抽象类。

Receiver:接收者角色,知道如何实施和执行一个请求相关的操作。

ConcreteCommand:将一个接收者对象与一个动作绑定,调用接收者相应的操作,实现execute.


16.3 使用命令模式实现问题


使用命令模式解决问题的类图

微信截图_20220609214606.png

注意:以上只是针对电灯做了开关,电视等其他的家电要在进行类的创建


16.4 命令模式在JDK中的应用


  • Spring框架的jdbc Template使用到了这个设计模式


16.5 命令模式的注意事项与细节


  • 将发起请求的对象与执行请求的对象解耦。
  • 容易设计一个命令队列。只要把命令对象放到列队,就可以多线程的执行命令。
  • 容易实现对请求的撤销和重做。


16.6 命令模式的使用场景


界面的一个按钮都是一条命令、模拟CMD(DOS命令)、订单的撤销/恢复、触发-反馈机制。


17.访问者模式


17.1 问题引入


问题引入(测评系统需求)

微信截图_20220609214704.png

17.2 访问者模式介绍

访问者模式简介

  • 封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
  • 主要将数据结构与数据操作分离,解决数据结构操作耦合性问题。
  • 访问者模式的工作原理:在被访问的类里面加一个对外提供接待访问者的接口。

访问者模式的原理类图

微信截图_20220609214713.png

访问者模式的角色及职务的分析

  • Visitor:是抽象访问者,为该对象结构中的ConcreteElement的每一个类声明一个visit操作。
  • ConcreteVisitor:是一个具体的访问值 实现每个由Vistor声明的操作,是每个操作实现的部分
  • ObjectStruture:能枚举它的元素,可以提供一个高层的接口,用来允许访问者访问元素。
  • Element:定义一个accept方法,接收一个访问者对象。
  • ConcreteElement:为具体元素,实现了 accept 方法。


17.3 使用访问者模式解决问题


使用访问修饰者解决问题的类图

微信截图_20220609214759.png

17.4 访问者模式之双分派


  • 所谓双分派是指不管类怎么变化,我们都能找到期望的方法运行。双分派意味着得到执行的操作取决于请求的种类和两个接收者的类型。


17.5 访问者模式的应用场景


  • 需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联),同时需要避免这些操作”污染“这些对象的类,可以选用访问者模式。
  • 如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的。


18.迭代器模式


18.1 迭代器介绍


迭代器的简介

  • 迭代器属于行为型模式。
  • 如果我们的 集合元素是用不同的方式实现的。有数组、集合等或者其他的存储方式,当客户端要 遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。
  • 迭代器模式:提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。

迭代器的原理类图

微信截图_20220609214834.png

18.2 迭代器模式在JDK中的应用


  • 在JDK—ArrayList集合中使用到了迭代器模式


18.3 迭代器模式的注意事项和细节


优点

  • 提供一个统一的方法遍历对象,客户不用在考虑聚合的类型,使用一种方法就可以遍历对象。
  • 隐藏了聚合的内部结构,客户端遍历集合的时候只能取到迭代器,而不会知道聚合的具体组成
  • 提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做 单一职责原则)。
  • 当要展示一组相似对象,或者遍历一组相同对象时使用,适合使用迭代器模式。

缺点

每个聚合对象都要有一个迭代器,会生成多个迭代器。


19.观察者模式


19.1 使用普通方式解决问题


问题引入(天气预报)

微信截图_20220609214913.png

解决问题的思路

微信截图_20220609214935.png

使用普通方式解决问题分析

  • 在WeatherData中,当增加一个第三方,都需要创建一个对应的第三方的公告板对象。并加入到datachange,不利于维护,也不是动态获取的。


19.2 观察者模式介绍


观察者模式原理


微信截图_20220609215016.png

19.3 使用观察者模式解决问题


观察者解决问题的类图

微信截图_20220609215213.png

19.4 观察者模式在JDK中的应用


  • JDK中的Observable类使用到了观察者模式。


20.中介者模式


20.1 使用普通方式解决问题


问题引入(智能家电)

微信截图_20220609215243.png

20.2 中介者模式介绍


中介者模式简介

  • 中介者模式:用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。
  • 中介者模式属于行为型模式,使代码易于维护。
  • 比如MVC模式,C(Controller控制器)、M(Model模型)、V(View视图)的中介者,在前后端交互时起到了中间人的作用。

中介者模式的原理类图

微信截图_20220609215259.png

简单理解中介者模式的类图

微信截图_20220609215336.png

20.2 使用中介者模式解决问题(智能家庭)

实现类图

微信截图_20220609215350.png

20.3 中介者模式注意事项与细节


  • 多个类相互耦合,会形成网状结构,使用中介者模式将网状结构分离为星型结构,进行耦合。
  • 减少类间依赖,降低了耦合,符合迪米特法则。
  • 中介者模式承担了较多的责任,一旦中介出现了问题,整个系统就会受到影响。
  • 如果设计不当,中介者对象本身会变得很复杂,这点在实际开发中,需要注意。


21.备忘录模式


21.1 使用普通方式解决问题


问题引入(游戏角色状态)

微信截图_20220609215437.png

普通方案解决类图

微信截图_20220609215443.png

普通解决方案问题分析

  • 一个对象,就对应一个保存对象状态的对象,这样当我们游戏的对象很多时,不利于管理,开销较大。
  • 传统的方式是简单地做备份,new出另一个对象出来,再把需要备份的数据放到这个新的对象,但是这就暴露了对象内部的细节。


21.2 备忘录模式介绍


备忘录模式简介

  • 备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
  • 可以这样理解备忘录模式:现实生活中的备忘录是用来记录某些要去做的事情或者是记录已经达成的共同意见的事情,以防止忘记。而在软件开发中,备忘录模式有相同的含义,备忘录对象主要用来记录一个对象的某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作。
  • 备忘录模式属于行为型模式。

备忘录模式的原理类图

微信截图_20220609215702.png

备忘录模式的角色及职务的分析

  • originator:对象(需要保存状态的对象)。
  • Memento:备忘录对象,负责保存好记录,即Originator内部状态。
  • Caretaker:守护者对象,负责保存多个备忘录对象,使用集合管理,提高效率。


21.3 使用备忘录模式解决问题


备忘录模式的类图

微信截图_20220609215736.png

21.4 备忘录模式的注意事项和细节


  • 给用户提供一种可以恢复状态的机制,可以使用户能够比较方便地找回到某个历史的状态。
  • 实现了信息的封装,使得用户不需要关心状态的保存细节。
  • 如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。


21.5 备忘录模式的适用场景


  • 后悔药。
  • 打游戏时的存档。
  • Windows中的 ctrl+z(撤销)。
  • IE中的后退。
  • 数据库的事务管理。

为了节约内存,备忘录模式可以和原型模式配合使用


22.解释器模式


22.1 使用传统方式解决问题


问题引入(四则运算)

微信截图_20220609215819.png

22.2 解释器模式介绍


解释器模式简介

  • 在编译原理中,一个算数表达式通过 词法分析器形成词法单元,而后这些词法单元再通过 语法分析器构建语法树,最终形成一颗抽象的语法分析树。这里的词法分析器语法分析器都可以看作是解释器。
  • 解释器并不是我们想象的一个简单的翻译器,解释器的内部结构非常饿复杂。可能含有多个解释器类,这些类之间相互关联。
  • 计时器模式:是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)

解释器模式的原理类图

微信截图_20220609215906.png

解释器模式的角色及职务的分析

微信截图_20220609215919.png

22.3 使用解释器模式来实现四则表达式


解决问题:计算a+b-c 的数字

使用解释器解决为问题的类图

微信截图_20220609220031.png

22.4 解释器模式在JDK中应用


  • Spring中的 SpelExpressionParse使用到了解释器模式


22.6 解释器模式的注意事项和细节


  • 当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象的语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性。
  • 使用解释器模式可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低。


22.5 解释器的应用场景


  • 应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
  • 一些重复出现的问题可以用一种简单的语句来表达。
  • 一个简单语法需要解释的场景。
  • 编译器、运算表达式计算、正则表达式、机器人等。


23. 状态模式


23.1 使用传统的方式解决问题


问题引入(APP抽奖活动)


23.2 状态模式的介绍

状态模式的简介

  • 状态模式:它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的关系,状态之间可以相互转换。
  • 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

状态模式的原理类图

微信截图_20220609220112.png

状态模式的角色及职务的分析

  • Context 类:为环境角色,用于维护State实例,这个实例定义当前状态。
  • State接口:是抽象状态角色,定义一个接口疯转与Context的一个特点接口相关行为。
  • ConcreteState类:是具体的状态角色,每一个子类实现一个与Context的一个状态相关行为。


23.3 使用状态模式解决抽奖问题


使用状态模式解决问题的类图

微信截图_20220609220119.png

23.4 状态模式的注意事项和细节


  • 代码有很强的可读性。状态模式将每个状态的行为封装到对应的一个类中。
  • 方便维护。不在需要使用if-else()语句来完成。
  • 符合”开闭原则“。容易增删状态。
  • 会产生很多的类。每一个状态都有一个对应的类,当状态过多时会产生很多的类,加大维护难度。


23.5 状态模式的应用场景


当一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求有不同的行为的时候,可以考虑使用状态模式。


24. 策略模式


24.1 使用普通方式解决问题


问题引入(鸭子问题)

微信截图_20220609220217.png

普通方式解决问题的类图

在Duck类(抽象类或者接口)中给定所有鸭子的共同行为,让不同的鸭子继承这个Duck,不同的鸭子可能还有不同的行为,让不同的鸭子自己实现。

微信截图_20220609220227.png微信截图_20220609220243.png


使用普通方式问题分析

微信截图_20220609220326.png

24.2 策略模式介绍


策略模式简介

  • 策略模式:策略模式中,定义算法簇,分别封装起来,让他们之间可以相互替换,次模式让算法的变化独立于使用算法的客户。
  • 这算法体现了几个设计原则:
  1. 把变化的代码从不变的代码中分离出来。
  2. 针对接口编程而不是具体的类(定义了策略接口)。
  3. 多用组合/聚合,少用继承(客户通过组合方式使用策略)。

策略模式的类图

微信截图_20220609220359.png

24.3 使用策略模式解决问题


思路分析与类图

策略模式:分别封装行为接口,实现算法簇,超类里放行为接口对象,在子类里具体设定行为对象。原则是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为的变化独立于算法的使用者。

微信截图_20220609220424.png


24.4 策略模式在JDK中的应用


  • Arrays的Comparator就使用了策略模式


24.5 策略模式的注意事项以及细节


  • 策略模式的关键:分析项目中变化部分与不变部分。
  • 策略模式的核心思想:多用组合/聚合,少用继承;用行为类组合,而不是行为的继承。
  • 体现了“对修改关闭,对扩展开放”原则。客户端增加行为不需要修改以前的代码,只需添加一种策略(或者行为)即可,避免了使用多重转移语句(if...else())。
  • 需要注意的是:每添加一个策略就要增加一个类,当策略过多时会导致类的数目庞大。


25.职责链模式


25.1 使用普通方式解决问题


问题引入(OA系统采购审批)

微信截图_20220609220704.png

普通方式实现问题的类图

微信截图_20220609220714.png

普通方式实现问题分析

微信截图_20220609220727.png

25.2 职责链模式介绍


职责链模式简介

  • 职责链模式又叫 责任链模式,为请求创建了一个接收者对象的链。这种模式对请求的发送者和接收者就行解耦。
  • 职责链通常每个接收者都包含另一个接收者的引用。如果一个对象不能处理该请求,那么他会把相同的请求传递给下一个接收者,依此类推。
  • 这种设计模式属于行为型模式

职责链模式的原理类图

微信截图_20220609220813.png

25.3 职责链模式在JDK中的应用


  • 在SpringMVC中的HandlerExecution类使用到了职责链模式。


25.4 职责链模式的注意事项和细节


  • 讲请求和处理分开,实现解耦,提高系统的灵活性。
  • 简化了对象,使对象不需要知道链的结构。
  • 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂。


25.5 职责链的应用场景


  • 有多个对象可以处理同一个请求,比如:多级请求、请假/加薪等审批流程、JavaWeb中Tomcat对Encoding的处理、拦截。
相关文章
|
设计模式 关系型数据库
【设计模式——学习笔记】设计模式简介+七大设计原则介绍(下)
【设计模式——学习笔记】设计模式简介+七大设计原则介绍
113 0
|
设计模式 前端开发 算法
设计模式之设计原则
程序设计的要遵循的一些理论,也可以理解为程序设计的一种要求和目标,是面向对象程序设计的基石,也是面向对象程序设计的质量保障和依据。
82 0
|
2月前
|
设计模式 Java 测试技术
Java设计模式-UML与设计原则(1)
Java设计模式-UML与设计原则(1)
|
3月前
|
设计模式 前端开发 JavaScript
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
|
4月前
|
设计模式 算法
交易链路设计原则&模式问题之中介者(Mediator)方法设计模式是什么,如何解决
交易链路设计原则&模式问题之中介者(Mediator)方法设计模式是什么,如何解决
|
6月前
|
设计模式 算法 Java
【设计模式系列笔记】设计模式与设计原则
设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 设计原则是一些通用的设计指导方针,它们提供了如何设计一个优秀的软件系统的基本思想和规则。指导着设计者如何组织代码以实现高内聚、低耦合、易扩展和易维护的软件系统。
81 4
|
设计模式 Java 关系型数据库
Java设计模式中的设计原则 2
Java设计模式中的设计原则
87 0
|
6月前
|
设计模式 Java 数据安全/隐私保护
设计模式之六大设计原则
设计模式之六大设计原则
69 0
|
6月前
|
设计模式 关系型数据库 程序员
【设计模式】设计原则
【1月更文挑战第12天】【设计模式】设计原则
|
设计模式 Java 程序员
【设计模式——学习笔记】设计模式简介+七大设计原则介绍(上)
【设计模式——学习笔记】设计模式简介+七大设计原则介绍
51 2

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    43
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    54
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    38
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    62
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    57
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    41
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    50
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    106
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    78