设计模式——行为型模式

一:目录
1. 策略模式(Strategy)
2.状态模式(State)
3.责任链模式(Chain Of Responsibility)
4.解释器模式(Interpreter)
5.命令模式(Command)
6.观察者模式(Observer)
7.备忘录模式(Memento)
8.迭代器模式(Iterator)
9.模板方法模式(Template Method)
10.访问者模式(Visitor)
11.中介者模式(Mediator)

二:详细介绍

2.1 策略模式(Strategy)

2.1.1 简介:

策略模式的主要目的是将算法的定义与使用分开,也就是将算法的行为与环境分开,将算法的定义放在专门的策略类汇总,每一个策略类封装了一种实现算法,使用算法的环境类针对抽象策略类进行编程,符合“依赖倒转原则”。

2.1.2 类图:
角色:
Context(环境类):环境类是使用算法的角色,它在解决某个问题时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。
Strategy(策略接口类):它为所支持的算法声明了抽象方法,是所有策略类的父类,可以是接口、抽象类、具体类。
ConcreteStrategy(具体策略类):它实现了在抽象策略类中声明的算法,运行时覆盖策略接口类,使用某种具体算法实现业务处理
在这里插入图片描述

2.1.3 实例:
Java SE的容器布局管理器,不同的布局封装成策略类算法

2.2 状态模式(State)

2.2.1 概论:
状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。

2.2.2 适用场景:
对象的行为依赖于它的状态(如某些属性值),状态的变化将导致行为的变化
在代码中包含大量和对象状态有关的条件语句,导致代码的可维护性和灵活性变差,不能方便的增加和删除状态,并且导致客户类与类库之间的耦合增强

2.2.3 优缺点:
优点:

  • 封装了状态的转换原则,可以对状态转换代码进行集中管理,而不是分散在一个个业务方法中
  • 将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为
  • 允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块

缺点:

  • 状态模式必然会增加系统中类和对象的数量,导致运行开销增大;
  • 状态模式的结构与实现都比较复杂,使用不当容易导致程序结构与代码的混乱,增加设计的难度;
  • 状态模式对“开闭原则”支持不太好,增加新的状态需要修改负责状态维护的代码;

2.2.3 类图:

在这里插入图片描述

2.2.4 实例:
在工作流与游戏开发中有广泛应用

2.3 责任链模式(Chain Of Responsibility)
2.3.1 描述:
责任链模式是一种对象的行为模式。在责任链模式中,对象持有下家的引用而连接成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上哪个对象最终处理这个请求,使得系统可以在不影响客户端的情况下动态的重新组织和分配责任。
纯与不纯的责任链:
纯责任链:要么处理请求,要么交给下家处理;不允许具体处理对象承担了一部分责任之后,又向下传递;一个请求必须被某一个处理对象所接收
不纯的责任链:纯的责任链很少见,能看到的基本上都是不纯的。

例如:击鼓传花,花束在每个人之间传递,当鼓声停下来,花在谁手中,谁就要喝酒行令。

在这里插入图片描述

2.3.2 适用场景:
有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻在确定,客户端只需将请求提交到责任链上,不需要关心请求的处理对象是谁以及如何处理
在不明确指定接收者的情况下,向一组对象中的一个提交一个请求
可动态指定一组对象处理请求,客户端可以动态创建责任链来处理请求,还可以改变链中处理者之间的顺序

2.3.3 类图:

在这里插入图片描述

2.4 解释器模式(Interpreter)

2.2.3 描述:

解释器模式为自定义语言的设计和实现提供了一种解决方案,他用于定义一组文法规则并通过这组文法规则来解释语言中的句子。
优点:
易于改变和扩展文法。在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法;
每一条文法规则都可以表示为一个类,因此可以方便的实现一个简单的语言;

2.2.3 类图:

抽象表达式角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称作解释操作
终结符表达式(Terminal Expression)角色:实现了抽象表达式角色所要求的接口,主要是interpret()方法;例如R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式;
非终结符表达式(Nonterminal Expcession)角色:文法中每一条规则都需要一个具体的非终结符表达式,它一般是文法中的运算符或者其他关键字。例如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。
环境(Context)角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200.这些信息需要存放到环境角色中,很多情况下使用Map做环境角色也就够了

在这里插入图片描述

2.5 命令模式(Command)

2.5.1 描述:
命令模式属于对象的行为模式,又称行动(Action)模式或者交易(Transaction)模式
命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供撤销、恢复功能
2.5.2 结构:
命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。
每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方与接收的一方独立开来,使得请求的一方不必知道接收的一方的接口,更不必知道请求如何接收,如何执行、何时执行、怎么被执行。
命令允许请求的乙方和接收请求的一方能够独立演化,从而具有以下的优点:

  • 命令模式使新的命令很容易被加到系统里
  • 允许接收请求的乙方决定是否要否决请求
  • 较容易的设计一个命令队列
  • 可以容易的实现对请求的撤销和恢复
  • 在需要的情况下,可以较容易地将命令记入日志

命令模式涉及到5个角色,分别为:

  • 客户端(Client)角色:创建一个具体命令(ConcreteCommand)对象并确定其接受者
  • 命令(Command)角色:声明了一个所有具体命令类的抽象接口
  • 具体命令(ConcreteCommand)角色:定义一个接收者与行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法
  • 请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法
  • 接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法

2.5.3 结构:
命令模式的优点:
更松散的耦合:命令模式使得发起命令的对象–客户端,和具体实现命令的对象-接收者对象完全解耦,也就是说发起命令的对象完全不知道具体实现对象是谁,也不知道如何实现。
更动态的控制:命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。
很自然的复合命令:命令模式中的命令对象能够很容易的组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大
更好的扩展性:由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,就可以使用这个命令对象,已有的实现完全不用变化。

2.5.4 类图:

在这里插入图片描述

2.5.4 代码:

interface Command {void execute();
}
class ConcreteCommand implements Command {private Receiver receiver;public ConcreteCommand(Receiver receiver) {this.receiver = receiver;}@Overridepublic void execute() {System.out.println(this.getClass().getName() + " execute.");receiver.action();}}class Invoker {private Command command;public Invoker(Command command) {this.command = command;}public void action() {System.out.println(getClass().getName() + " action.");command.execute();}
}class Receiver {public void action() {System.out.println(getClass().getName() + " action.");}
}public class CommandClient {public static void main(String[] args) {Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);Invoker invoker = new Invoker(command);invoker.action();}
}

2.6 观察者模式(Observer)

2.6.1 简介:
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式,模型-视图(Model/View)模式,源-监听器(Source/Listener)模式或者从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象。这个主体对象在状态上发生变化时,会通知所有观察者对象,使他们能够更新自己。
推模型和拉模型
在观察者模式中,分为推模型和拉模型
推模型:主题对象向观察者推送主题的详细信息,不管观察者是否需要,同送的信息通常是主体对象的部分或全部数据
拉模型:主体对象通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主体对象中拉数据。一般这种模型的实现,会把主体对象自身通过update()方法传递给观察者,这样观察者需要数据的时候,就可以通过这个引用来获取了

2.6.2 类图:

在这里插入图片描述

2.6.3 代码:

interface Observer {void update();
}class ConcreteObserver implements Observer {public ConcreteObserver(Subject subject) {subject.addObserver(this);}@Overridepublic void update() {System.out.println(getClass().getName() + " 得到通知.");}}abstract class Subject {Vector<Observer> observers = new Vector<>();void addObserver(Observer observer) {observers.addElement(observer);}void removeObserver(Observer observer) {observers.remove(observer);}public abstract void change();
}class ConcreteSubject extends Subject {private String state;@Overridepublic void change() {System.out.println(getClass().getName() + " state changed.");this.notifyObservers();}private void notifyObservers() {if(!CollectionUtils.isEmpty(observers)) {for(Observer observer : observers) {observer.update();}}}}public class ObserverClient {public static void main(String[] args) {Subject subject = new ConcreteSubject();Observer observer = new ConcreteObserver(subject);subject.change();}}

2.6.4 延伸:
Java从语言级别提供了Observer模式的实现,提供了一个接口(Observer)和一个类(Observable)
java.util.Observer
java.util.Observable

2.7 备忘录模式(Memento)

2.7.1 延伸:
备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式。
备忘录对象时一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态capture住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。

2.7.2 类图:

在这里插入图片描述

2.7.3 延伸:
2.7.4 延伸:

2.8 迭代器模式(Iterator)

2.9 模板方法模式(Template Method)

2.10 访问者模式(Visitor)

2.11 中介者模式(Mediator)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019 ICPC Asia Yinchuan Regional(9 / 13)

2019 ICPC Asia Yinchuan Regional A - Girls Band Party&#xff08;分组背包&#xff09; 每个物品有两个标签&#xff0c;名字&#xff0c;颜色&#xff0c;当名字是设置为奖赏时会对整体加上0.1 的贡献&#xff0c;如果颜色符合要求时 会对整体加上 0.2 的的贡献 但是有…

网络编程——常用协议解析

** 1、网络基础知识 ** 1.1> 什么是OSI模型 OSI 模型(Open System Interconnection model)是一个由国际标准化组织?提出的概念模型,试图?供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每层都可以提供抽象良好的…

在 ABP vNext 中编写仓储单元测试的问题一则

一、问题新项目是基于 ABP vNext 框架进行开发的&#xff0c;所以我要求为每层编写单元测试。在同事为某个仓储编写单元测试的时候&#xff0c;发现了一个奇怪的问题。他的对某个聚合根的 A 字段进行了更新&#xff0c;随后对某个导航属性 B 也进行了变更&#xff0c;最后通过仓…

TCP协议——三次握手与四次关闭

1. TCP协议基础 网络编程基础见&#xff0c;传送门 TCP是面向连接的&#xff0c;无论哪一方向另一方发送数据之前&#xff0c;都必须先在双方之间建立一条连接。 在TCP/IP协议中&#xff0c;TCP协议提供可靠的连接服务&#xff0c;连接是通过三次握手进行初始化的。 三次握手…

在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想

源码&#xff1a;https://github.com/Martin1994/JsonJitSerializerNuGet&#xff1a;https://www.nuget.org/packages/MartinCl2.Text.Json.Serialization/简介&#xff1a;Just-in-time 编译的 JSON 序列化&#xff0c;基于 System.Text.Json.NET Core 3.0 即将正式发布&…

E. Company(Codeforces Round #520 (Div. 2))

E. Company 给定一颗有nnn个节点的树&#xff0c;有mmm次询问&#xff0c;每次询问给定[l,r][l, r][l,r]&#xff0c;我们可以选择删除其中的一个点ppp&#xff0c;然后找到一个深度最深的rtrtrt&#xff0c;使得剩下的点都在rtrtrt的子树上。 考虑对编号为[l,r][l, r][l,r]中…

TCP协议——流量控制和拥塞控制

** 一、流量控制 ** 1.1 什么是流量控制 Sender won’t overflow receiver’s buffer by transmitting too much, too fast. &#xff08;防止发送方发的太快&#xff0c;耗尽接收方的资源&#xff0c;从而使接收方来不及处理&#xff09; 1.2 流量控制的一些知识点 &#x…

征集.NET中国峰会议题

月初做的调查《》&#xff0c;参与人数576人&#xff0c;愿意参与分享.NET Core经验的142人&#xff0c;今天发起分会场主题演讲和闪电演讲议题.2014年微软组织成立.NET基金会&#xff0c;微软在成为主要的开源参与者的道路上又前进了一步。2014年以来已经有众多知名公司加入.N…

TCP协议——粘包与拆包

TCP的基础 TCP协议基础&#xff0c;传送门 TCP协议流量控制&#xff0c;传送门 1.1 什么是TCP粘包/拆包 TCP是个“流”协议&#xff0c;所谓流&#xff0c;就是没有界限的一串数据。大家可以想想河里的流水&#xff0c;是连成一片的&#xff0c;其间并没有分界线。TCP底层并…

B. Lynyrd Skynyrd(倍增 + 区间最小值)

B. Lynyrd Skynyrd&#xff08;segment tree redouble&#xff09; 给定一个长度为nnn的排列ppp&#xff0c;一个长度为mmm的数组aaa&#xff0c;有mmm次询问&#xff0c;每次询问给定l,rl, rl,r&#xff0c;问在数组aaa中是否存在一个子序列构成的串是ppp的循环位移串&#…

你的通勤时间都去哪了?

大家好&#xff0c;我是Z哥。今天我来唠叨一下。最近无意间看到一份报告&#xff0c;关于我们职场人士上下班通勤时间的。有时候想想也挺无奈的&#xff0c;我们越想去发达一些的城市打拼&#xff0c;反而越被通勤这种琐碎的事情给耽误更多的奋斗时间。但是没办法&#xff0c;在…

规模化敏捷必须SAFe

引子&#xff1a;规模化敏捷转型从来不是一件容易的事情。当只有1-2个敏捷团队进行协同的时候&#xff0c;计划和工作同步是可控的。团队和产品负责人互相聊一聊&#xff0c;基本就能搞清楚需要做什么&#xff0c;一个简单的SOS架构&#xff08;Scrum of Scrums&#xff09;就能…

http1.0 http1.1 http2 之间的区别

一、HTTP基础 1.1 HTTP定义 HTTP协议&#xff08;HyperTextTransferProtocol&#xff0c;超文本传输协议&#xff09;是用于从WWW服务器传输超文本到本地浏览器的传输协议。 1.2 HTTP发展史 1.3 HTTP1.0 早先1.0的HTTP版本&#xff0c;是一种无状态、无连接的应用层协议。 …

B. Alyona and a tree(dsu on tree + bit)

B. Alyona and a tree&#xff08;dsu on tree bit&#xff09; 给定一颗以111号节点为根的树&#xff0c;每个点有点权aia_iai​&#xff0c;边有边权&#xff0c;如果vvv控制了点uuu&#xff0c;当且仅当uuu是vvv的子树中的节点且dis(u,v)≤audis(u, v) \leq a_udis(u,v)≤…

HTTP get post put delte等

超文本传输协议&#xff08;HTTP, HyperText Transfer Protocol&#xff09;是一种无状态的协议&#xff0c;它位于OSI七层模型的传输层。HTTP客户端会根据需要构建合适的HTTP请求方法&#xff0c;而HTTP服务器会根据不同的HTTP请求方法做出不同的响应。 HTTP版本与HTTP请求方…

P1600 [NOIP2016 提高组] 天天爱跑步(线段树合并,lca)

P1600 [NOIP2016 提高组] 天天爱跑步 给定一颗有nnn个点的树&#xff0c;有mmm个人在树上移动&#xff0c;第iii个人从sis_isi​点&#xff0c;移动到tit_iti​点&#xff0c;且他们按照最短路移动&#xff0c;每秒移动一条边的距离&#xff0c; 点iii在wiw_iwi​时刻有一个观…

漫画:程序员一时单身一时爽,一直单身...有点惨

1妹子没吃早饭早啊敲哥&#xff0c;你在吃早饭啊嗯啊&#xff0c;你吃了吗&#xff1f;没呢&#xff0c;早上实在是太赶了&#xff0c;没来得及嗯...那我还是换个地方吃吧免得馋着你。。。2代码重要还是女朋友重要女朋友能哄好&#xff0c;代码能哄好吗&#xff1f;写代码是赚钱…

P3564 [POI2014]BAR-Salad Bar(ST表 + 二分)

P3564 [POI2014]BAR-Salad Bar 给定一个长度为nnn的数组&#xff0c;里面元素只有111跟−1-1−1&#xff0c;问选出一个长度为lenlenlen的区间使得&#xff0c;这个区间的前缀和时刻大于零&#xff0c;后缀和时刻大于零&#xff0c;输出最大长度lenlenlen&#xff0c; 考虑枚…

【招聘(深圳)】迈瑞招.NET 开发Leader和PM

应用开发管理&#xff08;开发leader&#xff09;工作职责&#xff1a;1.负责应用开发小组管理&#xff1b;2.协助项目经理制定项目计划和控制项目进度&#xff1b;3.评估用户需求&#xff0c;设计解决方案、系统功能&#xff0c;并带领开发小组进行交付&#xff1b;4.对开发过…

Java RMI,Socket,HttpClient

Java RMI Java远程方法调用&#xff08;Java Remote Method Invocation&#xff09; 是Java编程语言里&#xff0c;一种用于实现远程过程调用的应用程序编程接口。 它使客户机上运行的程序可以调用远程服务器上的对象。 远程方法调用特性使Java编程人员能够在网络环境中分布操…