精华内容
下载资源
问答
  • 设计模式之行为型模式

    千次阅读 2020-08-19 17:22:50
    行为型模式 一、模板方法模式 (一)定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以改变该算法结构的情况下重定义该算法的某些特定步骤。 (二)模式说明: 例如,去银行办理业务...

    行为型模式

    一、模板方法模式

    (一)定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

    (二)模式说明:
    例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现

    (三)构成要素:
    在这里插入图片描述
    (四)应用案例
    出国留学手续一般经过以下流程:索取学校资料,提出入学申请,办理因私出国护照、出境卡和公证,申请签证,体检、订机票、准备行装,抵达目标学校等,其中有些业务对各个学校是一样的,但有些业务因学校不同而不同,所以比较适合用模板方法模式来实现。

    在这里插入图片描述

    二、策略模式

    (一)定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

    (二)模式说明:
    1、在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等,超市促销可以釆用打折、送商品、送积分等方法。
    2、在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等。

    (三)构成要素:
    在这里插入图片描述
    (四)应用案例
    关于大闸蟹的做法有很多种,我们以清蒸大闸蟹和红烧大闸蟹两种方法为例,介绍策略模式的应用。
    定义一个大闸蟹加工的抽象策略类(CrabCooking),里面包含了一个做菜的抽象方法 CookingMethod();然后,定义清蒸大闸蟹(SteamedCrabs)和红烧大闸蟹(BraisedCrabs)的具体策略类,它们实现了抽象策略类中的抽象方法;最后,定义一个厨房(Kitchen)环境类,它具有设置和选择做菜策略的方法,客户类通过厨房类获取做菜策略。
    在这里插入图片描述

    三、命令模式

    (一)定义:命令模式定义为:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

    (二)模式说明:
    1、在软件开发系统中,常常出现“方法的请求者”与“方法的实现者”之间存在紧密的耦合关系。这不利于软件功能的扩展与维护。
    2、在现实生活中,这样的例子也很多,例如,电视机遥控器(命令发送者)通过按钮(具体命令)来遥控电视机(命令接收者)。

    (三)构成要素:
    在这里插入图片描述

    (四)应用案例
    客户去餐馆可选择的早餐有肠粉、河粉和馄饨等,客户可向服务员选择以上早餐中的若干种,服务员将客户的请求交给相关的厨师去做。这里的点早餐相当于“命令”,服务员相当于“调用者”,厨师相当于“接收者”,所以用命令模式实现比较合适。
    首先,定义一个早餐类(Breakfast),它是抽象命令类,有抽象方法 cooking(),说明要做什么;再定义其子类肠粉类(ChangFen)、馄饨类(HunTun)和河粉类(HeFen),它们是具体命令类,实现早餐类的 cooking() 方法,但它们不会具体做,而是交给具体的厨师去做;具体厨师类有肠粉厨师(ChangFenChef)、馄蚀厨师(HunTunChef)和河粉厨师(HeFenChef),他们是命令的接收者。
    在这里插入图片描述

    四、责任链模式

    (一)定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。。

    (二)模式说明:
    在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这增加了难度。

    (三)构成要素:
    在这里插入图片描述

    (四)应用案例
    假如规定学生请假小于或等于 2 天,班主任可以批准;小于或等于 7 天,系主任可以批准;小于或等于 10 天,院长可以批准;其他情况不予批准;这个实例适合使用职责链模式实现。

    首先,定义一个领导类(Leader),它是抽象处理者,包含了一个指向下一位领导的指针 next 和一个处理假条的抽象处理方法 handleRequest(int LeaveDays);然后,定义班主任类(ClassAdviser)、系主任类(DepartmentHead)和院长类(Dean),它们是抽象处理者的子类,是具体处理者,必须根据自己的权力去实现父类的 handleRequest(int LeaveDays) 方法,如果无权处理就将假条交给下一位具体处理者,直到最后;客户类负责创建处理链,并将假条交给链头的具体处理者(班主任)。
    在这里插入图片描述

    五、状态模式

    (一)定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

    (二)模式说明:
    对这种有状态的对象编程,传统的解决方案是:将这些所有可能发生的情况全都考虑到,然后使用 if-else 语句来做状态判断,再进行不同情况的处理。但当对象的状态很多时,程序会变得很复杂。而且增加新的状态要添加新的 if-else 语句,这违背了“开闭原则”,不利于程序的扩展。

    以上问题如果采用“状态模式”就能很好地得到解决。状态模式的解决思想是:当控制一个对象状态转换的条件表达式过于复杂时,把相关“判断逻辑”提取出来(抽象成对象),放到一系列的状态类当中,这样可以把原来复杂的逻辑判断简单化

    (三)构成要素:
    在这里插入图片描述

    (四)应用案例
    实例中包含了“不及格”“中等”和“优秀” 3 种状态,当学生的分数小于 60 分时为“不及格”状态,当分数大于等于 60 分且小于 90 分时为“中等”状态,当分数大于等于 90 分时为“优秀”状态,我们用状态模式来实现这个程序。

    首先,定义一个抽象状态类(AbstractState),其中包含了环境属性、状态名属性和当前分数属性,以及加减分方法 addScore(intx) 和检查当前状态的抽象方法 checkState();然后,定义“不及格”状态类 LowState、“中等”状态类 MiddleState 和“优秀”状态类 HighState,它们是具体状态类,实现 checkState() 方法,负责检査自己的状态,并根据情况转换;最后,定义环境类(ScoreContext),其中包含了当前状态对象和加减分的方法 add(int score),客户类通过该方法来改变成绩状态。
    在这里插入图片描述

    六、观察者模式

    (一)定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,这种模式有时又称作发布-订阅模式、模型-视图模式。

    (二)模式说明:
    在现实世界中,许多对象并不是独立存在的,其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变。例如,某种商品的物价上涨时会导致部分商家高兴,而消费者伤心;微信公众号与微信用户消息推送等等

    (三)构成要素:
    在这里插入图片描述

    (四)应用案例
    当“人民币汇率”升值时,进口公司的进口产品成本降低且利润率提升,出口公司的出口产品收入降低且利润率降低;当“人民币汇率”贬值时,进口公司的进口产品成本提升且利润率降低,出口公司的出口产品收入提升且利润率提升。

    这里的汇率(Rate)类是抽象目标类,它包含了保存观察者(Company)的 List 和增加/删除观察者的方法,以及有关汇率改变的抽象方法 change(int number);而人民币汇率(RMBrate)类是具体目标, 它实现了父类的 change(int number) 方法,即当人民币汇率发生改变时通过相关公司;公司(Company)类是抽象观察者,它定义了一个有关汇率反应的抽象方法 response(int number);进口公司(ImportCompany)类和出口公司(ExportCompany)类是具体观察者类,它们实现了父类的 response(int number) 方法,即当它们接收到汇率发生改变的通知时作为相应的反应。
    在这里插入图片描述

    七、中介者模式

    (一)定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。

    (二)模式说明:
    在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是“网状结构”,它要求每个对象都必须知道它需要交互的对象。例如,每个人必须记住他(她)所有朋友的电话;而且,朋友中如果有人的电话修改了,他(她)必须告诉其他所有的朋友修改,这叫作“牵一发而动全身”,非常复杂。而解决的方法只要在网上建立一个每个朋友都可以访问的“通信录”就解决了

    (三)构成要素:
    在这里插入图片描述

    (四)应用案例
    房地产交流平台是“房地产中介公司”提供给“卖方客户”与“买方客户”进行信息交流的平台,比较适合用中介者模式来实现
    首先,定义一个中介公司(Medium)接口,它是抽象中介者,它包含了客户注册方法 register(Customer member) 和信息转发方法 relay(String from,String ad);再定义一个韶关房地产中介(EstateMedium)公司,它是具体中介者类,它包含了保存客户信息的 List 对象,并实现了中介公司中的抽象方法。
    然后,定义一个客户(Qistomer)类,它是抽象同事类,其中包含了中介者的对象,和发送信息的 send(String ad) 方法与接收信息的 receive(String from,Stringad) 方法的接口。
    最后,定义卖方(Seller)类和买方(Buyer)类,它们是具体同事类,是客户(Customer)类的子类,它们实现了父类中的抽象方法,通过中介者类进行信息交流
    在这里插入图片描述

    八、迭代者模式

    (一)定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

    (二)模式说明:
    在现实生活以及程序设计中,经常要访问一个聚合对象中的各个元素,如“数据结构”中的链表遍历,通常的做法是将链表的创建和遍历都放在同一个类中,但这种方式不利于程序的扩展,如果要更换遍历方法就必须修改程序源代码,这违背了 “开闭原则”。
    “迭代器模式”能较好地克服以上缺点,它在客户访问类与聚合类之间插入一个迭代器,这分离了聚合对象与其遍历行为,对客户也隐藏了其内部细节,且满足“单一职责原则”和“开闭原则”,如 Java 中的 Collection、List、Set、Map 等都包含了迭代器。 将迭代单独封装成一个类
    (三)构成要素:

    在这里插入图片描述

    (四)应用案例
    首先,设计一个婺源景点(WyViewSpot)类来保存每张图片的名称与简介;再设计一个景点集(ViewSpotSet)接口,它是抽象聚合类,提供了增加和删除婺源景点的方法,以及获取迭代器的方法。

    然后,定义一个婺源景点集(WyViewSpotSet)类,它是具体聚合类,用 ArrayList 来保存所有景点信息,并实现父类中的抽象方法;再定义婺源景点的抽象迭代器(ViewSpotltemtor)接口,其中包含了查看景点信息的相关方法。

    最后,定义婺源景点的具体迭代器(WyViewSpotlterator)类,它实现了父类的抽象方法。图 2 所示是其结构图。

    九、访问者模式

    (一)定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。

    (二)模式说明:
    在现实生活中,有些集合对象中存在多种不同的元素,且每种元素也存在多种不同的访问者和处理方式。例如,公园中存在多个景点,也存在多个游客,不同的游客对同一个景点的评价可能不同;医院医生开的处方单中包含多种药元素,査看它的划价员和药房工作人员对它的处理方式也不同,划价员根据处方单上面的药品名和数量进行划价,药房工作人员根据处方单的内容进行抓药。

    (三)构成要素:

    在这里插入图片描述

    (四)应用案例
    艺术公司利用“铜”可以设计出铜像,利用“纸”可以画出图画;造币公司利用“铜”可以印出铜币,利用“纸”可以印出纸币。对“铜”和“纸”这两种元素,两个公司的处理方法不同,所以该实例用访问者模式来实现比较适合

    首先,定义一个公司(Company)接口,它是抽象访问者,提供了两个根据纸(Paper)或铜(Cuprum)这两种元素创建作品的方法;再定义艺术公司(ArtCompany)类和造币公司(Mint)类,它们是具体访问者,实现了父接口的方法;然后,定义一个材料(Material)接口,它是抽象元素,提供了 accept(Company visitor)方法来接受访问者(Company)对象访问;再定义纸(Paper)类和铜(Cuprum)类,它们是具体元素类,实现了父接口中的方法;最后,定义一个材料集(SetMaterial)类,它是对象结构角色,拥有保存所有元素的容器 List,并提供让访问者对象遍历容器中的所有元素的 accept(Company visitor)方法。

    在这里插入图片描述

    十、备忘录模式

    (一)定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。

    (二)模式说明:
    其实很多应用软件都提供了这项功能,如 Word、记事本、Photoshop、Eclipse 等软件在编辑时按 Ctrl+Z 组合键时能撤销当前操作,使文档恢复到之前的状态;还有在 IE 中的后退键、数据库事务管理中的回滚操作、玩游戏时的中间结果存档功能、数据库与操作系统的备份操作、棋类游戏中的悔棋功能等都属于这类。

    (三)构成要素:

    在这里插入图片描述

    (四)应用案例
    假如有西施、王昭君、貂蝉、杨玉环四大美女同你相亲,你可以选择其中一位作为你的爱人;当然,如果你对前面的选择不满意,还可以重新选择,但希望你不要太花心;这个游戏提供后悔功能,用“备忘录模式”设计比较合适。

    首先,先设计一个美女(Girl)类,它是备忘录角色,提供了获取和存储美女信息的功能;然后,设计一个相亲者(You)类,它是发起人角色,它记录当 前时刻的内部状态信息(临时妻子的姓名),并提供创建备忘录和恢复备忘录数据的功能;最后,定义一个美女栈(GirlStack)类,它是管理者角色,负责对备忘录进行管理,用于保存相亲者(You)前面选过的美女信息,不过最多只能保存 4 个,提供后悔功能。在这里插入图片描述

    十一、解释器模式

    (一)定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。

    (二)模式说明:
    在软件开发中,会遇到有些问题多次重复出现,而且有一定的相似性和规律性。如果将它们归纳成一种简单的语言,那么这些问题实例将是该语言的一些句子,这样就可以用“编译原理”中的解释器模式来实现了。

    (三)构成要素:

    在这里插入图片描述

    (四)应用案例
    假如“韶粵通”公交车读卡器可以判断乘客的身份,如果是“韶关”或者“广州”的“老人” “妇女”“儿童”就可以免费乘车,其他人员乘车一次扣 2 元。

    分析:本实例用“解释器模式”设计比较适合,首先设计其文法规则如下。
    < expression > ::= < city >的< person >
    < city > ::= 韶关|广州
    < person > ::= 老人|妇女|儿童

    然后,根据文法规则按以下步骤设计公交车卡的读卡器程序的类图。

    • 定义一个抽象表达式(Expression)接口,它包含了解释方法 interpret(String info)。
    • 定义一个终结符表达式(Terminal Expression)类,它用集合(Set)类来保存满足条件的城市或人,并实现抽象表达式接口中的解释方法 interpret(Stringinfo),用来判断被分析的字符串是否是集合中的终结符。
    • 定义一个非终结符表达式(AndExpressicm)类,它也是抽象表达式的子类,它包含满足条件的城市的终结符表达式对象和满足条件的人员的终结符表达式对象,并实现 interpret(String info) 方法,用来判断被分析的字符串是否是满足条件的城市中的满足条件的人员。
    • 最后,定义一个环境(Context)类,它包含解释器需要的数据,完成对终结符表达式的初始化,并定义一个方法 freeRide(String info) 调用表达式对象的解释方法来对被分析的字符串进行解释。其结构图如图 3 所示。

    参考:
    [1] 软件设计模式概述

    展开全文
  • 设计模式——行为型模式

    千次阅读 2019-04-23 21:47:51
    1. 策略模式(Strategy) 2.状态模式(State) 3.责任链模式(Chain Of Responsibility) 4.解释器模式(Interpreter) 5.命令模式(Command) 6.观察者模式(Observer) 7.备忘录模式(Memento) 8.迭代器模式...

    一:目录
    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;
         }
         @Override
         public 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);
         }
         @Override
         public 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;
         
         @Override
         public 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)

    展开全文
  • 备忘录模式(Memento Pattern)属于行为型模式。行为型模式涉及到算法和对象间职责的分配;行为型模式不仅描述对象或类的模式,还描述它们之间的通信模式。行为型模式刻划了在运行时难以跟踪的复杂的控制流;它们将你...

    行为型设计模式:备忘录模式(Memento Pattern)

    CSDN专栏: 设计模式(UML/23种模式)

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

    备忘录模式(Memento Pattern)属于行为型模式。行为型模式涉及到算法和对象间职责的分配;行为型模式不仅描述对象或类的模式,还描述它们之间的通信模式。行为型模式刻划了在运行时难以跟踪的复杂的控制流;它们将你的注意力从控制流转移到对象间的联系方式上来。行为型模式主要包括:Chain of Responsibility模式、Command模式、Interpreter模式、Iterator模式、Mediator模式、Memento模式、Observer模式、State模式、Strategy模式、Template Method模式和Visitor模式。行为型模式在某种程度上具有相关性。

    模式简介

    GOF的《设计模式》指出Memento模式的意图是:
    在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

    有时有必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复过来,需要实现检查点和取消机制 , 而要实现这些机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到它们先前的状态。但是对象通常封装了其部分或所有的状态信息 , 使得其状态不能被其他对象访问,也就不可能在该对象之外保存其状态。而暴露其内部状态又将违反封装的原则,可能有损应用的可靠性和可扩展性。

    Memento模式适用于以下场景:

    • 必须保存一个对象在某一个时刻的 (部分)状态, 这样以后需要时它才能恢复到先前的状态。
    • 如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

    模式图解

    Memento模式的UML示例如下:

    Memento模式示例

    Memento模式的工作过程如下:

    • Memtoto备忘录存储原发器对象的内部状态。Originator原发器根据需要决定备忘录存储原发器的哪些内部状态;禁止其他对象访问备忘录。
    • Originator原发器创建一个备忘录, 用以记录当前时刻它的内部状态,并且可以使用备忘录恢复内部状态.。
    • Caretaker管理器负责保存备忘录但是不能对内容进行操作或检查。
    • Caretaker管理器向Originator原发器请求一个备忘录, 保留一段时间后, 将其送回给Originator原发器

    Memento模式的有益效果如下:

    • 有利于保持封装边界:使用备忘录可以避免暴露一些只应由原发器管理却又必须存储在原发器之外的信息。
    • 有利于简化原发器: Originator负责保持客户请求过的内部状态版本,让客户管理它们请求的状态将会简化Originator, 并且使得客户工作结束时无需通知原发器。
    • 管理和维护备忘录的成本较高:创建、恢复和删除备忘录的操作均有较大开销。

    Command模式:命令可使用备忘录来为可撤消的操作维护状态。Iterator模式: 如前所述备忘录可用于迭代。

    模式实例

    [TODO]

    系列文章

    参考文献

    展开全文
  • Java 设计模式 行为型模式 + 案例

    千次阅读 2016-10-23 12:06:03
    行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式策略模式(Strategy) 策略模式定义了一系列算法,并将每个算法...

    行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

    策略模式(Strategy)

    策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,也可以设计一个抽象类(可有可无,属于辅助类),提供辅助函数

    //统一的接口
        public interface ICalculator {  
             public int calculate(String exp);  
        }  
    
        //抽象类,作为辅助类,可以提供一些你认为需要的方法
        public abstract class AbstractCalculator {  
            public int[] split(String exp,String opt){  
                String array[] = exp.split(opt);  
                int arrayInt[] = new int[2];  
                arrayInt[0] = Integer.parseInt(array[0]);  
                arrayInt[1] = Integer.parseInt(array[1]);  
                return arrayInt;  
            }  
        } 
    
        //接口的三个实现类:
        public class Plus extends AbstractCalculator implements ICalculator {  
            public int calculate(String exp) {  
                int arrayInt[] = split(exp,"[+]");  
                return arrayInt[0]+arrayInt[1];  
            }  
        }   
    
        public class Minus extends AbstractCalculator implements ICalculator {  
            public int calculate(String exp) {  
                int arrayInt[] = split(exp,"-");  
                return arrayInt[0]-arrayInt[1];  
            }  
        }
    
        public class Multiply extends AbstractCalculator implements ICalculator {  
            public int calculate(String exp) {  
                int arrayInt[] = split(exp,"[*]");  
                return arrayInt[0]*arrayInt[1];  
            }  
        }  
    
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
                String exp = "2+8";  
                ICalculator cal = new Plus();  
                int result = cal.calculate(exp);  
                System.out.println(result);  
            }  
        }

    策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
    我们之前在学校TreeSet排序的时候,有一种叫做资客户化排序的方式,就是给TreeSet传一个比较器对象,这个其实就是使用了策略模式

    模板方法模式(Template Method)

    模板方法模式,就是指:一个抽象类中,有一个主方法,再定义1…n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类的方法,实现对子类的调用其实就是我们之前所说的: 子类重新/实现父类中的方法,那么调用该方法的时候则是调用到了子类中重写之后的方法

    //父类
        public abstract class AbstractCalculator {  
    
            /*实现对本类其它方法的调用*/  
            public final int calculate(String exp,String opt){  
                int array[] = split(exp,opt);  
                return calculate(array[0],array[1]);  
            }  
    
            /*被子类重写的方法*/  
            abstract public int calculate(int num1,int num2);  
    
            public int[] split(String exp,String opt){  
                String array[] = exp.split(opt);  
                int arrayInt[] = new int[2];  
                arrayInt[0] = Integer.parseInt(array[0]);  
                arrayInt[1] = Integer.parseInt(array[1]);  
                return arrayInt;  
            }  
        }       
    
        //子类
        public class Plus extends AbstractCalculator {  
            public int calculate(int num1,int num2) {  
                return num1 + num2;  
            }  
        }  
    
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
                String exp = "8+8";  
                AbstractCalculator cal = new Plus();  
                int result = cal.calculate(exp, "\\+");  
                System.out.println(result);  
            }  
        }

    观察者模式(Observer)

    观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。
    我们在GUI那一章学习的事件监听机制就是可以这种设置模式来构建的代码

    //观察者接口
        public interface Observer {  
             public void update();  
        }  
    
        //观察者1
        public class Observer1 implements Observer {  
            public void update() {  
                System.out.println("observer1 has received!");  
            }  
        }  
    
        //观察者2
        public class Observer2 implements Observer {  
            public void update() {  
                System.out.println("observer2 has received!");  
            }  
        } 
    
        //被观察者接口
        public interface Subject {  
    
            /*增加观察者*/  
            public void add(Observer observer);  
    
            /*删除观察者*/  
            public void del(Observer observer);  
    
            /*通知所有的观察者*/  
            public void notifyObservers();  
    
            /*自身的操作*/  
            public void operation();  
        }  
    
        //被观察者的一个抽象实现 提供基本的实现
        public abstract class AbstractSubject implements Subject {  
    
            private Vector<Observer> vector = new Vector<Observer>();  
            public void add(Observer observer) {  
                vector.add(observer);  
            }  
    
            public void del(Observer observer) {  
                vector.remove(observer);  
            }  
    
            public void notifyObservers() {  
                Iterator<Observer> it = vector.iterator();
                while(it.hasNext()){
            Observer next = it.next();
            next.update();
                }
            }  
        }
    
        //我们自己的一个被观察者实现  里面可以有我们自己的各种属性和方法
        public class MySubject extends AbstractSubject {  
            public void operation() {  
                System.out.println("update self!");  
                notifyObservers();  
            }  
        } 
    
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
                Subject sub = new MySubject();  
                sub.add(new Observer1());  
                sub.add(new Observer2());  
                sub.operation();  
            }  
        }

    迭代器模式(Iterator)

    顾名思义,迭代器模式就是顺序访问聚集中的对象,一般来说,集合中非常常见,如果对集合类比较熟悉的话,理解本模式会十分轻松。

    public interface Collection {  
            public Iterator iterator();  
    
            /*取得集合元素*/  
            public Object get(int i);  
    
            /*取得集合大小*/  
            public int size();  
        }  
    
        public interface Iterator {  
            //前移  上一个元素
            public Object previous();  
    
            //后移  下一个元素
            public Object next();  
            public boolean hasNext();  
    
            //取得第一个元素  
            public Object first();  
        }  
    
        public class MyCollection implements Collection {  
            //假设这个集合内部是由数组实现
            public String string[] = {"A","B","C","D","E"};  
    
            public Iterator iterator() {  
                return new MyIterator(this);  
            }  
            public Object get(int i) {  
                return string[i];  
            }  
            public int size() {  
                return string.length;  
            }  
        }  
    
        //这个地方其实一般会设计为内部类
        public class MyIterator implements Iterator {  
    
            private Collection collection;  
            private int pos = -1;  
    
            public MyIterator(Collection collection){  
                this.collection = collection;  
            }  
            public Object previous() {  
                if(pos > 0){  
                    pos--;  
                }  
                return collection.get(pos);  
            }  
            public Object next() {  
                if(pos<collection.size()-1){  
                    pos++;  
                }  
                return collection.get(pos);  
            }  
            public boolean hasNext() {  
                if(pos<collection.size()-1){  
                    return true;  
                }else{  
                    return false;  
                }  
            }  
            public Object first() {  
                pos = 0;  
                return collection.get(pos);  
            }  
        }
    
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
                Collection collection = new MyCollection();  
                Iterator it = collection.iterator();  
    
                while(it.hasNext()){  
                    System.out.println(it.next());  
                }  
            }  
        }

    责任链模式(Chain of Responsibility)

    责任链模式,有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。
    (web应该中学习到的Filter其实就是一个责任链设计模式)

    public interface Handler {  
            public void operator();  
        } 
    
        public class MyHandler implements Handler {  
    
            private String name;  
            private Handler handler;  
    
            public MyHandler(String name) {  
                this.name = name;  
            } 
    
            public Handler getHandler() {  
                return handler;  
            }  
            public void setHandler(Handler handler) {  
                this.handler = handler;  
            }  
    
            public void operator() {  
                System.out.println("name = "+name);  
                if(getHandler()!=null){  
                    getHandler().operator();  
                }  
            }  
        }  
    
        /测试类
        public class Test {  
    
            public static void main(String[] args) {  
                MyHandler h1 = new MyHandler("h1");  
                MyHandler h2 = new MyHandler("h2");  
                MyHandler h3 = new MyHandler("h3");  
    
                h1.setHandler(h2);  
                h2.setHandler(h3);  
    
                h1.operator();  
            }  
        }

    命令模式(Command)

    命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者(司令、命令、士兵)相互解耦,任何一方都不用去依赖其他人的具体实现,只需要做好自己的事儿就行,司令员要的是结果,不会去关注到底士兵是怎么实现的。

    //命令执行的接口
            public interface Command {  
            public void exe();  
        }
        //具体实现的命令
        public class MyCommand implements Command {  
    
            private Receiver receiver;  
    
            public MyCommand(Receiver receiver) {  
                this.receiver = receiver;  
            }  
            public void exe() {  
                receiver.action();  
            }  
        }   
    
        //被调用者(士兵)
        public class Receiver {  
            public void action(){  
                System.out.println("command received!");  
            }  
        } 
        //调用者(司令员)
        public class Invoker {  
    
            private Command command;  
    
            public Invoker(Command command) {  
                this.command = command;  
            }  
    
            public void action(){  
                command.exe();  
            }  
        }
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
                Receiver receiver = new Receiver();  
                Command cmd = new MyCommand(receiver);  
                Invoker invoker = new Invoker(cmd);  
                invoker.action();  
            }  
        }
    

    这个很好理解,命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开。
    对于大多数请求-响应模式的功能,比较适合使用命令模式。

    备忘录模式(Memento)

    也可以叫备份模式,主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。

    //原始类,里面有需要保存的属性value
        public class Original {  
    
            private String value;  
    
            public String getValue() {  
                return value;  
            }  
    
            public void setValue(String value) {  
                this.value = value;  
            }  
    
            public Original(String value) {  
                this.value = value;  
            }  
    
            //创建备忘录对象用来存储属性值
            public Memento createMemento(){  
                return new Memento(value);  
            }  
    
            //还原属性值
            public void restoreMemento(Memento memento){  
                this.value = memento.getValue();  
            }  
        }       
    
        //备忘录类,用来保存value值
        public class Memento {  
    
            private String value;  
    
            public Memento(String value) {  
                this.value = value;  
            }  
    
            public String getValue() {  
                return value;  
            }  
    
            public void setValue(String value) {  
                this.value = value;  
            }  
        } 
    
        //存储备忘录的类,持有Memento类的实例
        public class Storage {  
    
            private Memento memento;  
    
            public Storage(Memento memento) {  
                this.memento = memento;  
            }  
    
            public Memento getMemento() {  
                return memento;  
            }  
    
            public void setMemento(Memento memento) {  
                this.memento = memento;  
            }  
        }  
    
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
    
                // 创建原始类  
                Original origi = new Original("egg");  
    
                // 创建备忘录  
                Storage storage = new Storage(origi.createMemento());  
    
                // 修改原始类的状态  
                System.out.println("初始化状态为:" + origi.getValue());  
                origi.setValue("niu");  
                System.out.println("修改后的状态为:" + origi.getValue());  
    
                // 回复原始类的状态  
                origi.restoreMemento(storage.getMemento());  
                System.out.println("恢复后的状态为:" + origi.getValue());  
            }  
        } 

    状态模式(State)

    核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿QQ来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作。再比如交通灯,有红黄绿三种状态,每种状态下操作也是不一样的

    //状态类
        public class State {  
    
            private String value;  
    
            public String getValue() {  
                return value;  
            }  
    
            public void setValue(String value) {  
                this.value = value;  
            }  
    
            public void method1(){  
                System.out.println("execute the first opt!");  
            }  
    
            public void method2(){  
                System.out.println("execute the second opt!");  
            }  
        }
    
        //Context类可以实现切换状态
        public class Context {  
    
            private State state;  
    
            public Context(State state) {  
                this.state = state;  
            }  
    
            public State getState() {  
                return state;  
            }  
    
            public void setState(State state) {  
                this.state = state;  
            }  
    
            public void method() {  
                if (state.getValue().equals("state1")) {  
                    state.method1();  
                } else if (state.getValue().equals("state2")) {  
                    state.method2();  
                }  
            }  
        } 
    
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
    
                State state = new State();  
                Context context = new Context(state);  
    
                //设置第一种状态  
                state.setValue("state1");  
                context.method();  
    
                //设置第二种状态  
                state.setValue("state2");  
                context.method();  
            }  
        }  

    访问者模式(Visitor)

    访问者模式把数据结构和作用于结构上的操作解耦合,使得对数据操作可相对自由地演化。访问者模式适用于数据结构相对稳定,算法又易变化的系统。

    因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。

    简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。

    //访问者接口
        public interface Visitor {  
            public void visit(Subject sub);  
        } 
        //访问者的一个具体实现
        public class MyVisitor implements Visitor {  
            public void visit(Subject sub) {  
                System.out.println("visit the subject:"+sub.getSubject());  
            }  
        }  
    
        //被访问者接口
        public interface Subject {  
            public void accept(Visitor visitor);  
            public String getSubject();  
        }  
        //被访问者的一个具体实现
        public class MySubject implements Subject {  
            public void accept(Visitor visitor) {  
                visitor.visit(this);  
            }  
            public String getSubject() {  
                return "love";  
            }  
        } 
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
    
                Visitor visitor = new MyVisitor();  
                Subject sub = new MySubject();  
                sub.accept(visitor);      
            }  
        } 

    该模式适用场景:如果我们想为一个现有的类增加新功能,不得不考虑几个事情:

    1、新功能会不会与现有功能出现兼容性问题?
    2、以后会不会再需要添加?
    3、如果类不允许修改代码怎么办?

    面对这些问题,最好的解决方法就是使用访问者模式,访问者模式适用于数据结构相对稳定的系统,把数据结构和算法解耦

    中介者模式(Mediator)

    这个模式也是用来降低类和类之间的耦合的,因为如果类和类之间有依赖关系的话,不利于功能的拓展和维护,因为只要修改一个对象,其它关联的对象都得进行修改。如果使用中介者模式,只需关心和Mediator类的关系,具体类类之间的关系及调度交给Mediator就行

    //中间者接口
        public interface Mediator {  
            public void createMediator();  
            public void workAll();  
        }       
        //中介者的一个具体实现
        public class MyMediator implements Mediator {  
    
            private User user1;  
            private User user2;  
    
            public User getUser1() {  
                return user1;  
            }  
    
            public User getUser2() {  
                return user2;  
            }  
            public void createMediator() {  
                user1 = new User1(this);  
                user2 = new User2(this);  
            }  
            public void workAll() {  
                user1.work();  
                user2.work();  
            }  
        }   
        //抽象类
        public abstract class User {  
    
            private Mediator mediator;  
    
            public Mediator getMediator(){  
                return mediator;  
            }  
    
            public User(Mediator mediator) {  
                this.mediator = mediator;  
            }  
            public abstract void work();  
        }  
        //User1
        public class User1 extends User {  
            public User1(Mediator mediator){  
                super(mediator);  
            }  
            public void work() {  
                System.out.println("user1 exe!");  
            }  
        }
        //User2
        public class User2 extends User {  
            public User2(Mediator mediator){  
                super(mediator);  
            }  
            public void work() {  
                System.out.println("user2 exe!");  
            }  
        }  
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
                Mediator mediator = new MyMediator();  
                mediator.createMediator();  
                mediator.workAll();  
            }  
        }  

    适用场景
    在面向对象编程中,一个类必然会与其他的类发生依赖关系,完全独立的类是没有意义的。一个类同时依赖多个类的情况也相当普遍,既然存在这样的情况,说明,一对多的依赖关系有它的合理性,适当的使用中介者模式可以使原本凌乱的对象关系清晰,但是如果滥用,则可能会带来反的效果。一般来说,只有对于那种同事类之间是网状结构的关系,才会考虑使用中介者模式。可以将网状结构变为星状结构,使同事类之间的关系变的清晰一些。

    解释器模式(Interpreter)

    在以下情况下可以使用解释器模式:

    • 有一个简单的语法规则,比如一个sql语句,如果我们需要根据sql语句进行其他语言的转换,就可以使用解释器模式来对语句进行解释。
    • 一些重复发生的问题,比如加减乘除四则运算,但是公式每次都不同,有时是a+b-c*d,有时是a*b+c-d,等等等等个,公式千变万化,但是都是由加减乘除四个非终结符来连接的,这时我们就可以使用解释器模式。
    //解释器接口(这里的是专门解析数学运算表达式)
        public interface Expression {  
             public int interpret(Context context);  
        }  
        //加法
        public class Plus implements Expression {  
            public int interpret(Context context) {  
                return context.getNum1()+context.getNum2();  
            }  
        }  
        //减法
        public class Minus implements Expression {  
            public int interpret(Context context) {  
                return context.getNum1()-context.getNum2();  
            }  
        }  
    
        //Context类是一个上下文环境类 持有运行中所需的数据
        public class Context {  
    
            private int num1;  
            private int num2;  
    
            public Context(int num1, int num2) {  
                this.num1 = num1;  
                this.num2 = num2;  
            }  
    
            public int getNum1() {  
                return num1;  
            }  
            public void setNum1(int num1) {  
                this.num1 = num1;  
            }  
            public int getNum2() {  
                return num2;  
            }  
            public void setNum2(int num2) {  
                this.num2 = num2;  
            }  
        }  
    
        //测试类
        public class Test {  
    
            public static void main(String[] args) {  
    
                     // 计算9+2-8的值  
                    int result = new Minus().interpret(new Context(
                            new Plus().interpret(new Context(9, 2)), 8));
            //相当于:new Minus().interpret(new Context(11, 8));
            System.out.println(result);  
            }  
        }  
    
    
    展开全文
  • 设计模式---十一个行为型模式

    热门讨论 2017-01-16 11:32:10
    十一个行为型模式
  • Java经典设计模式共有21中,分为三大类:创建型模式(5种)、结构型模式(7种)和行为型模式(11种)。本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之五大创建型模式...
  • Java经典设计模式共有21中,分为三大类:创建型模式(5种)、结构型模式(7种)和行为型模式(11种)。本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型模式(附实例...
  • 美团2016校园招聘 研发工程师(一) 以下设计模式中,哪一项不属于结构性模式? A 适配器模式 B 代理模式 C 命令模式 D 装饰模式 正确答案 : C知识点创建型模式,共五种...行为型模式,共十一种:策略模式、
  • 1.创建型模式 前面讲过,社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象的使用分开也就成为了必然趋势。因为对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而...
  • 设计模式(三)之行为型模式

    千次阅读 2016-11-23 13:02:24
    本篇是关于设计模式的最后一讲,会讲到第三种设计模式——行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式...
  • 23种设计模式分析(5):行为型模式

    千次阅读 2014-04-06 23:21:13
     Observer(观察者)模式又被称作发布-订阅(Publish-Subscribe)模式,是一种对象的行为型模式。《设计模式》一书对Observer是这样描述的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有...
  • 适用性在下列情况下使用中介者模式: 1. 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且那一理解 2. 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象 3. 想定制...
  • 说明:文末可下载案例源码   创建(为类实例化提供指南) 原型模式 原型模式(Prototype Pattern)是用于创建重复的对象,并且与重新...这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直...
  • 一、 职责链模式-Chain of Responsibility Pattern 1) 请求的链式处理——职责链模式(一) “一对二”,“过”,“过”……这声音熟悉吗?你会想到什么?对!纸牌。在类似“斗地主”这样的纸牌游戏中,某人出牌...
  • 用一个对象封装一系列的对象交互,中介者使对象需要显示的相互作用,从而使其耦合松散,而且可以独立的改变他们之间的独立。 个人理解 当多个对象之间存在着过多的耦合时,可以通过中介者模式进行解耦,将具体的...
  • 访问者模式(Visitor Pattern)是一个行为型模式,其定义如下:Represent an operation to beperformed on the elements of an object structure.Visitor lets you define a new operation withoutchanging the ...
  • 观察者模式是设计模式中的“超级模式”,其应用随处可见,在之后几篇文章里,我将向大家详细介绍观察者模式。    “红灯停,绿灯行”,在日常生活中,交通信号灯装点着我们的城市,指挥着日益拥挤的城市交通...
  • 中介者模式的定义为:Define an object that encapsulates how a set of objects interact.Mediator promotesloose coupling by keeping objects from referring to each other explicitly,and it lets you vary ...
  • 设计模式 ( 十五 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力。当对象们连接在一起时,它们就可以相互提供服务和信息。 通常来说,当某个...
  • 总体来说设计模式分为三大类... 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。  其实还有两类:并发
  • 中介者模式又称为调停者模式,它是一种对象行为型模式。  在中介者模式中,我们引入了用于协调其他对象 / 类之间相互调用的中介者类,为了让系统具有更好的灵活性和可扩展性,通常还提供了抽象...
  • 访问者模式是一种对象行为型模式。  访问者模式的结构较为复杂,其结构如图 2 所示:  在访问者模式结构图中包含如下几个角色:  ● Vistor (抽象...
  • 模板方法(Template Method)-----类行为型模式 ( 学习笔记)1.意图 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method 使得子类可以改变一个算法的结构即可重定义该算法的某些特定步骤。 2...
  • 特此说明:对访问者模式理解不是特别透彻,若有误,请指正,谢谢! 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象,可以接受...
  • 设计模式(二)结构型模式

    千次阅读 2018-08-04 20:58:08
    Java 中一般认为有23 种设计模式,我们需要所有的都会,但是其中常用的几种设计模式应该去掌握。 下面列出了所有的设计模式。... 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模...
  • 设计模式;结构型模式;...适配器模式(Adapter Pattern)属于结构型模式,又称为包装器(Wrapper)模式。结构型模式涉及到如何组合类和对象以获得更大的结构;结构型类模式采用继承机制来组合接口或实现。
  • 设计模式总结—结构型模式

    千次阅读 2013-04-11 10:06:51
    结构型模式是指如何组合类和对象以获得更合理的结构。所以结构型模式分为类结构模式和对象结构模式这两种。类结构模式是指采用继承机制来组合接口或实现。组合结构模式是指通过组合一些对象,从而实现新的功能。  ...
  • 中介者模式

    千次阅读 2019-09-25 20:33:35
    中介者模式属于行为型模式。 介绍 意图:用一个中介对象来封装一系列的对象交互,中介者使各对象需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 主要解决:对象与对象之间存在大量的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 62,274
精华内容 24,909
关键字:

以下不属于行为型模式的是