软件体系结构与设计模式第十章 责任链模式
- 格式:ppt
- 大小:295.50 KB
- 文档页数:19
通俗易懂设计模式解析——责任链模式前言今天我们介绍的是责任链模式【Chain of Responsibility Pattern】。
对于责任链模式理解起来还是比较容易的。
例如在公司请假、三天以内部门经理批准即可,但是三到七天可能就需要总监批准了、七天以上需要副总裁批准。
对于这么一个需求最初的解决方案就是if-else语句判断。
但是一旦请假的模式增加一种则需要对多重if-else进行修改,这就违背了开闭原则。
这个时候就可以采用责任链模式来解决其问题。
责任链模式为请求创建一个接收者对象的链。
这种模式给予请求的类型,对请求的发送者和接收者进行解耦。
责任链模式介绍一、来由在软件系统中,经常会有一个请求可能会被多个对象处理。
但是每一次都是被一个对象处理。
又不能确定是哪一个对象。
如果显示指定每一个对象。
会对请求发送者和接收者造成紧耦合。
那么如何做到对请求的发送者和接收者进行解耦。
并且在运行时自行决定处理请求的对象呢?二、意图避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
三、案例四、责任链模式代码示例看上述案例图,主要涉及到两个部分:抽象处理者:定义一个处理请求的接口具体处理者:实现处理请求的接口、可以选择是自己处理或者传递给下一个接收者。
包含对下一个接收处理者的引用。
责任链模式的组成部分还是比较简单的。
我们看这么一个案例,还是用户结算时金额计算的案例。
根据用户的会员等级进行对应的折扣结算。
普通用户全额计算、普通会员95折计算、黄金会员9折计算、钻石会员7折计算:我们首先看看不使用责任链模式如何处理:namespace ChainofResponsibility_Pattern{class Program{ static void Main(string[] args){decimal Money =200M;var memberType = MemberType.GoldMember;//普通会员,95折计算if (memberType == MemberType.Member){Console.WriteLine($"普通会员,95折计算,最后金额为{Money * 0.95M}");}//黄金会员,9折计算else if(memberType == MemberType.GoldMember){Console.WriteLine($"黄金会员,9折计算,最后金额为{Money * 0.9M}");}//钻石会员,7折计算else if(memberType == MemberType.DiamondsMember){Console.WriteLine($"钻石会员,7折计算,最后金额为{Money * 0.7M}");}//无会员,全额计算else{Console.WriteLine($"无会员,全额计算,最后金额为{Money}");}}public enum MemberType{[Description("无会员")]NoMember = 1,[Description("普通会员")]Member = 2,[Description("黄金会员")]GoldMember = 3,[Description("钻石会员")]DiamondsMember = 4}}}这里我们可以看到我们使用了多个if条件判断完成的此需求(或者switch语句)。
责任链模式(Chain of Responsibility)责任链模式,有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。
但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。
先看看关系图:Abstracthandler类提供了get和set方法,方便MyHandle类设置和修改引用对象,MyHandle类是核心,实例化后生成一系列相互持有的对象,构成一条链。
[java]view plaincopy1.public interface Handler {2.public void operator();3.}[java]view plaincopy1.public abstract class AbstractHandler {2.3.private Handler handler;4.5.public Handler getHandler() {6.return handler;7. }8.9.public void setHandler(Handler handler) {10.this.handler = handler;11. }12.13.}[java]view plaincopy1.public class MyHandler extends AbstractHandler implements Handler {2.3.private String name;4.5.public MyHandler(String name) { = name;7. }8.9.@Override10.public void operator() {11. System.out.println(name+"deal!");12.if(getHandler()!=null){13. getHandler().operator();14. }15. }16.}[java]view plaincopy1.public class Test {2.3.public static void main(String[] args) {4. MyHandler h1 = new MyHandler("h1");5. MyHandler h2 = new MyHandler("h2");6. MyHandler h3 = new MyHandler("h3");7.8. h1.setHandler(h2);9. h2.setHandler(h3);10.11. h1.operator();12. }13.}输出:h1deal!h2deal!h3deal!此处强调一点就是,链接上的请求可以是一条链,可以是一个树,还可以是一个环,模式本身不约束这个,需要我们自己去实现,同时,在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。
设计模式之职责链模式 相信⼤家都玩过类似于“⽃地主”的纸牌游戏,某⼈出牌给他的下家,下家看看⼿中的牌,如果要不起,则将出牌请求转发给他的下家,其下家再进⾏判断。
⼀个循环下来,如果其他⼈都要不起该牌,则最初的出牌者可以打出新牌。
在这个过程中,纸牌作为⼀个请求沿着⼀条链在传递,每⼀位纸牌的玩家都可以处理该请求。
在设计模式中,也有⼀种专门⽤于处理这种请求链式的模式,它就是职责链模式。
⼀职责链模式概述1.1 职责链模式简介职责链(Chain of Responsibility)模式:避免将请求发送者与接受者耦合在⼀起,让多个对象都有机会接受请求,将这些对象连成⼀条链,并且沿着这条链传递请求,直到有对象处理它为⽌。
职责链模式是⼀种对象⾏为型模式。
1.2 需求需求背景:M公司承接了某企业SCM(Supply Chain Management,供应链管理)系统的开发任务,其中包含⼀个采购审批⼦系统。
该企业的采购审批是分级进⾏的,即根据采购⾦额的不同由不同层次的主管⼈员来审批:主任可以审批5万元以下(不包括5万)的采购单,副董事长可以审批5万~10万(不包括10万)的采购单,50万元以及以上的采购单就需要开董事会讨论决定,如下图所⽰:1.3 类图1.4 代码实现1.4.1 抽象执⾏者类// 抽象执⾏者类class AbstractApprover{public:explicit AbstractApprover(string strName = ""){} // 防⽌隐式转换virtual ~AbstractApprover(){}void SetSucessor(AbstractApprover* pSucessor){m_pSucessor = pSucessor;}virtual void ProcessRequest(CRequestX *) = 0;protected:string m_strName;AbstractApprover* m_pSucessor;};1.4.2 主管类// 主管类class CDirector : public AbstractApprover{public:explicit CDirector(string strName = ""){m_strName = strName;}~CDirector(){}void ProcessRequest(CRequestX *pRequest){if (pRequest->m_fAmount < 50000){cout << "主管:"<< m_strName.c_str() << "审批采购单:" << pRequest->m_strNumber.c_str() << "" << pRequest->m_fAmount << "" << "元," << "采购⽬的" << pRequest->m_strPurpose.c_str() << endl; }else{m_pSucessor->ProcessRequest(pRequest);}}};1.4.3 副总裁类// 副总裁类class CVicePresident : public AbstractApprover{public:explicit CVicePresident(string strName = ""){m_strName = strName;}~CVicePresident(){}void ProcessRequest(CRequestX *pRequest){if (pRequest->m_fAmount < 100000){cout << "副总裁:"<< m_strName.c_str() << "审批采购单:" << pRequest->m_strNumber.c_str() << "" << pRequest->m_fAmount << "" << "元," << "采购⽬的" << pRequest->m_strPurpose.c_str() << endl; }else{m_pSucessor->ProcessRequest(pRequest);}}};1.4.4 总裁类// 总裁类class CPresident : public AbstractApprover{public:explicit CPresident(string strName = ""){m_strName = strName;}~CPresident(){}void ProcessRequest(CRequestX *pRequest){if (pRequest->m_fAmount < 500000){cout << "总裁:"<< m_strName.c_str() << "审批采购单:" << pRequest->m_strNumber.c_str() << "" << pRequest->m_fAmount << "" << "元," << "采购⽬的" << pRequest->m_strPurpose.c_str() << endl; }else{m_pSucessor->ProcessRequest(pRequest);}}};1.4.5 董事会类// 董事会类class CCongress : public AbstractApprover{public:explicit CCongress(string strName = ""){m_strName = strName;}~CCongress(){}void ProcessRequest(CRequestX *pRequest){cout << "董事会:"<< m_strName << "审批采购单:" << pRequest->m_strNumber << "" <<pRequest->m_fAmount << "" << "元," << "采购⽬的" << pRequest->m_strPurpose << endl;}};1.5 测试#include "stdio.h"#include "responsibility.h"void main(){// 创建职责链AbstractApprover *PDirector = new CDirector("主管");AbstractApprover *pVicePresident = new CVicePresident("副总裁");AbstractApprover *pPresident = new CPresident("总裁");AbstractApprover *pCongress = new CCongress("董事会");PDirector->SetSucessor(pVicePresident);pVicePresident->SetSucessor(pPresident);pPresident->SetSucessor(pCongress);// 构造采购请求单并发送审批请求CRequestX* request1 = new CRequestX(45000.00,"MANULIFE201706001","购买PC和显⽰器");PDirector->ProcessRequest(request1);CRequestX* request2 = new CRequestX(60000.00,"MANULIFE201706002","2017开发团队活动");PDirector->ProcessRequest(request2);CRequestX* request3 = new CRequestX(160000.00,"MANULIFE201706003","2017公司年度旅游");PDirector->ProcessRequest(request3);CRequestX* request4 = new CRequestX(800000.00,"MANULIFE201706004","租⽤新临时办公楼");PDirector->ProcessRequest(request4);return;}⼆职责链模式总结2.1 主要优点 (1)使得⼀个对象⽆需知道是其他哪⼀个对象处理其请求,对象仅需知道该请求会被处理即可,且链式结构由客户端创建 => 降低了系统的耦合度 (2)在系统中增加⼀个新的具体处理者⽆须修改原有系统源代码,只需要在客户端重新建⽴链式结构即可 => 符合开闭原则2.2 主要缺点 (1)由于⼀个请求没有⼀个明确地接受者 => ⽆法保证它⼀定会被处理 (2)对于较长的职责链 => 系统性能有⼀定影响且不利于调试 (3)如果建⽴链不当,可能会造成循环调⽤ => 导致系统进⼊死循环2.3 应⽤场景 (1)有多个对象处理同⼀个请求且⽆需关⼼请求的处理对象时谁以及它是如何处理的 => ⽐如各种审批流程 (2)可以动态地指定⼀组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序 => ⽐如各种流程定制。
职责链设计模式一、什么是职责链设计模式职责链设计模式(Chain of Responsibility)是一种行为设计模式,它允许多个对象按照其顺序依次处理请求,直到请求被处理或者到达链的末尾。
每个对象在收到请求后,可以选择将其处理,然后传递给下一个对象,也可以选择不处理,从而将请求传递给下一个对象。
这种模式将请求发送者和接收者解耦,使得多个对象都有可能处理请求,提高了代码的灵活性。
二、应用场景职责链设计模式通常应用于以下场景:1.处理请求的对象不确定,并且可以在运行时动态添加或删除对象。
2.需要按照特定顺序对请求进行处理。
3.请求的发送者和接收者需要解耦,避免耦合度过高。
4.想要在不明确指定接收者的情况下,动态地指定处理该请求的对象。
三、实现方式职责链设计模式的核心思想是将请求通过一个对象链传递,并让不同的对象依次处理请求。
下面是实现该模式的一般步骤:1.定义一个抽象处理器(Handler)类,其中包含一个指向下一个处理器的引用。
2.派生具体处理器(ConcreteHandler)类,实现请求处理的具体逻辑,并在需要时将请求传递给下一个处理器。
3.在客户端代码中创建处理器链的实例,并将请求发送到链的起始位置。
四、实例演示以一个账单审批系统为例,系统中有三个级别的审批者:经理、副总经理和总经理。
账单金额小于1000元的由经理审批,小于5000元的由副总经理审批,其余由总经理审批。
1. 定义抽象处理器类public abstract class Approver {protected Approver nextApprover;public void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}public abstract void approve(Bill bill);}2. 派生具体处理器类public class Manager extends Approver {@Overridepublic void approve(Bill bill) {if (bill.getAmount() < 1000) {System.out.println("Manager approved the bill with amount: " + bil l.getAmount());} else if (nextApprover != null) {nextApprover.approve(bill);}}}public class VicePresident extends Approver {@Overridepublic void approve(Bill bill) {if (bill.getAmount() < 5000) {System.out.println("Vice President approved the bill with amount: " + bill.getAmount());} else if (nextApprover != null) {nextApprover.approve(bill);}}}public class President extends Approver {@Overridepublic void approve(Bill bill) {System.out.println("President approved the bill with amount: " + bill. getAmount());}}3. 创建处理器链的实例并发送请求public class Main {public static void main(String[] args) {Approver manager = new Manager();Approver vicePresident = new VicePresident();Approver president = new President();manager.setNextApprover(vicePresident);vicePresident.setNextApprover(president);Bill bill1 = new Bill(800);manager.approve(bill1);Bill bill2 = new Bill(3000);manager.approve(bill2);Bill bill3 = new Bill(10000);manager.approve(bill3);}}4. 运行结果Manager approved the bill with amount: 800Vice President approved the bill with amount: 3000President approved the bill with amount: 10000五、优缺点优点:1.降低了请求发送者和接收者之间的耦合度,使得处理请求的对象可以独立变化。
责任链模式(ChainofResponsibilityPattern)责任链模式是一种对象的行为模式。
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
请求在这个链上传递,直到链上的某一个对象决定处理此请求。
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态的重新组织链和分配责任。
一、责任链模式的结构1、责任链模式涉及的角色抽象处理者角色(Handler):定义出一个处理请求的接口。
如果需要,接口可以定义出一个方法,以设定和返回下家的引用。
这个角色通常由一个Java抽象类或Java接口实现。
图中的聚合关系给出了具体子类对下家的引用,抽象方法handlerRequest()规范了子类处理请求的操作。
具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。
由于处理者持有下家引用,因此,如果需要,具体处理者可以访问下家。
抽象处理者角色public abstract class Handler{protected Handler successor;//定义下家的引用public abstract void handleRequest();//处理方法,调用此方法处理请求public void setSuccessor(Handler successor)//赋值方法,调用此方法设置下家{this.successor = successor;}public Handler getSuccessor()//取值方法,得到下家对象{return successor;}}具体处理者角色,如果有下家,就将请求传给下家,否则就处理请求public class ConcreteHandler extends Handler{public void handleRequest(){if (getSuccessor() != null){System.out.println("The request is passed to " + getSuccessor());getSuccessor().handleRequest();}else{System.out.println("The request is handled here.");}}}客户端角色public class Client{static private Handler handler1, handler2;public static void main(String[] args){handler1 = new ConcreteHandler();handler2 = new ConcreteHandler();handler1.setSuccessor(handler2);handler1.handleRequest();}}客户端创建了2个处理者对象,并指定第一个处理者对象的下家是第2个处理者对象,而第2个处理者对象没有下家。
深⼊理解设计模式(12):职责链模式⼀、什么是职责链模式客户端发出⼀个请求,链上的对象都有机会来处理这⼀请求,⽽客户端不需要知道谁是具体的处理对象。
这样就实现了请求者和接受者之间的解耦,并且在客户端可以实现动态的组合职责链。
使编程更有灵活性。
定义:使多个对象都有机会处理请求,从⽽避免了请求的发送者和接受者之间的耦合关系。
将这些对象连成⼀条链,并沿着这条链传递该请求,直到有对象处理它为⽌。
其过程实际上是⼀个递归调⽤。
要点主要是: 1、有多个对象共同对⼀个任务进⾏处理。
2、这些对象使⽤链式存储结构,形成⼀个链,每个对象知道⾃⼰的下⼀个对象。
3、⼀个对象对任务进⾏处理,可以添加⼀些操作后将对象传递个下⼀个任务。
也可以在此对象上结束任务的处理,并结束任务。
3、客户端负责组装链式结构,但是客户端不需要关⼼最终是谁来处理了任务。
⼆、职责链模式的结构 责任链模式涉及到的⾓⾊如下所⽰:● 抽象处理者(Handler)⾓⾊:定义出⼀个处理请求的接⼝。
如果需要,接⼝可以定义出⼀个⽅法以设定和返回对下家的引⽤。
这个⾓⾊通常由⼀个Java抽象类或者Java接⼝实现。
上图中Handler类的聚合关系给出了具体⼦类对下家的引⽤,抽象⽅法handleRequest()规范了⼦类处理请求的操作。
● 具体处理者(ConcreteHandler)⾓⾊:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。
由于具体处理者持有对下家的引⽤,因此,如果需要,具体处理者可以访问下家三、职责链模式的优缺点优点:职责链模式的最主要功能就是:动态组合,请求者和接受者解耦。
请求者和接受者松散耦合:请求者不需要知道接受者,也不需要知道如何处理。
每个职责对象只负责⾃⼰的职责范围,其他的交给后继者。
各个组件间完全解耦。
动态组合职责:职责链模式会把功能分散到单独的职责对象中,然后在使⽤时动态的组合形成链,从⽽可以灵活的分配职责对象,也可以灵活的添加改变对象职责。
设计模式之责任链模式责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它将请求的发送者和接受者解耦,并且允许多个对象都有机会处理这个请求。
责任链模式通常被用于处理对象间的请求传递,使得每个对象都有机会处理请求,同时避免请求的发送者和接受者之间的耦合关系。
责任链模式由一系列的处理对象组成,每个处理对象都负责处理特定的请求,并且对下一个处理对象的引用。
当一个请求被发送时,责任链上的每个处理对象依次判断是否能处理该请求,如果能则立即处理,如果不能则传递给下一个处理对象。
这样,请求发送者并不需要知道请求最终会被哪个对象处理。
责任链模式的结构包括以下几个角色:1. 抽象处理者(Handler):定义处理请求的接口,通常包含一个指向下一个处理者的引用。
2. 具体处理者(ConcreteHandler):实现抽象处理者的接口,具体处理请求的逻辑,并且可根据需要传递请求给下一个处理者。
下面通过一个实际的例子来说明责任链模式的应用。
假如在一个电商系统中,有三个订单处理的环节:商品审核、支付检查和库存验证。
货物在途过程中,可能会出现商品信息不完整、支付异常或库存不足的情况。
我们可以使用责任链模式来设计这样一个订单处理系统。
首先,定义一个抽象处理者(Handler)接口,包含一个处理请求的方法,并且可以设置下一个处理者的引用。
```javapublic interface Handler {void setNextHandler(Handler handler);void handleRequest(Order order);}```然后,实现具体的处理者(ConcreteHandler)类,包括商品审核处理者、支付检查处理者和库存验证处理者。
每个具体处理者都实现了处理请求的方法,并且根据需要判断是否需要传递请求给下一个处理者。
```javapublic class ProductCheckHandler implements Handler {private Handler nextHandler;@Overridepublic void setNextHandler(Handler handler) {this.nextHandler = handler;}@Overridepublic void handleRequest(Order order) {// 商品审核逻辑// ...// 如果有下一个处理者,则传递请求if (nextHandler != null) {nextHandler.handleRequest(order);}}}public class PaymentCheckHandler implements Handler { private Handler nextHandler;@Overridepublic void setNextHandler(Handler handler) {this.nextHandler = handler;}@Overridepublic void handleRequest(Order order) {// 支付检查逻辑// ...// 如果有下一个处理者,则传递请求if (nextHandler != null) {nextHandler.handleRequest(order);}}}public class StockCheckHandler implements Handler { private Handler nextHandler;@Overridepublic void setNextHandler(Handler handler) {this.nextHandler = handler;}@Overridepublic void handleRequest(Order order) {// 库存验证逻辑// ...// 如果有下一个处理者,则传递请求if (nextHandler != null) {nextHandler.handleRequest(order);}}}```最后,在客户端代码中组装责任链,并将请求发送给第一个处理者。
责任链模式校验参数用法-概述说明以及解释1.引言1.1 概述责任链模式是一种软件设计模式,用于解耦发送者和接收者之间的关系。
在该模式中,多个对象依次处理同一个请求,直到其中一个对象能够处理该请求为止。
这种机制可以使请求的发送者与接收者之间的耦合度降低,同时提高系统的灵活性和可扩展性。
校验参数是软件开发中十分常见的操作,它用于验证用户输入的数据是否符合预期的要求。
参数校验的重要性在于保证系统的安全性和稳定性,避免了不合法的参数进入系统,从而防止了潜在的安全风险和逻辑错误。
责任链模式在校验参数中具有广泛的应用。
通过使用责任链模式,可以将不同的参数校验逻辑划分为一系列独立的节点,每个节点专门负责一个具体的校验操作。
当一个参数被提交进行校验时,它会依次经过这些节点,每个节点都可以根据自己的业务逻辑进行参数校验,并对校验结果进行处理。
如果某个节点能够处理该参数,则校验流程终止;如果所有节点都无法处理该参数,则表示参数校验失败。
责任链模式在校验参数中的应用具有以下优势:1. 解耦性高:责任链模式将校验逻辑拆分为多个节点,各节点之间相互独立,通过定义好的接口进行交互,降低了各节点之间的耦合度。
2. 可扩展性强:通过增加或删除节点,可以方便地对参数校验的流程进行扩展或修改,满足不同场景下的需求变化。
3. 灵活性好:每个节点可以自行决定是否处理该参数,以及如何处理。
因此,可以根据具体的业务需求,对参数校验的流程进行定制化处理,提高了系统的灵活性和可维护性。
1.2文章结构1.2 文章结构本文主要介绍了责任链模式在参数校验中的应用,通过以下几个方面进行阐述。
首先,引言部分会对整篇文章进行一个概述,介绍责任链模式以及校验参数的重要性,明确文章的目的和意义。
其次,正文部分将分为三个主要部分进行讲解。
首先,我们会详细介绍责任链模式的定义和原理,包括责任链模式的基本结构、角色以及工作流程。
然后,我们将重点探讨校验参数在软件开发中的重要性,包括对输入数据的合法性进行校验以保证系统的安全性和稳定性。
设计模式:责任链模式设计模式:责任链模式⼀、前⾔责任链(chain of responsibility)模式很像异常的捕获和处理,当⼀个问题发⽣的时候,当前对象看⼀下⾃⼰是否能够处理,不能的话将问题抛给⾃⼰的上级去处理,但是要注意这⾥的上级不⼀定指的是继承关系的⽗类,这点和异常的处理是不⼀样的。
所以可以这样说,当问题不能解决的时候,将问题交给另⼀个对象去处理,就这样⼀直传递下去直⾄当前对象找不到下线了,处理结束。
如下图所⽰,处于同等层次的类都继承⾃Support类,当当前对象不能处理的时候,会根据预先设定好的传递关系将问题交给下⼀个⼈,可以说是“近⽔楼台先得⽉”,就看有没有能⼒了。
我们也可以看作是⼤家在玩⼀个传谜语猜谜底的⼩游戏,按照座位的次序以及规定的顺序传递,如果⼀个⼈能回答的上来游戏就结束,否则继续向下传,如果所有⼈都回答不出来也会结束。
这样或许才是责任链的本质,体现出了同等级的概念。
⼆、代码Trouble 类:(数据结构)1package zyr.dp.cor;23public class Trouble {45private int number;6public Trouble( int number){7this.number=number;8 }9public int getNumber() {10return number;11 }12public String toString(){13return "问题编号:["+number+"]";14 }15 }Support 类:(抽象类,使⽤了模板⽅法)1package zyr.dp.cor;23public abstract class Support {45protected abstract boolean resolve(Trouble trouble); 67 String name;8 Support next;910public Support(String name){=name;12 }1314public String toString() {15return "对象:<"+name+">";16 }1718public Support setAndReturnNext(Support next){19this.next=next;20return next;21 }2223public final void support(Trouble trouble){24if(resolve(trouble)){25 done(trouble);26 }else if(next!=null){27 next.support(trouble);28 }else{29 fail(trouble);30 }31 }3233protected void fail(Trouble trouble) {34 System.out.println(this+"解决问题失败,"+trouble);35 }3637protected void done(Trouble trouble) {38 System.out.println(this+"已经解决问题,"+trouble);39 }4041 }NoSupport 类:1package zyr.dp.cor;23public class NoSupport extends Support {45public NoSupport(String name) {6super(name);7 }89protected boolean resolve(Trouble trouble) {10return false;11 }1213 }OddSupport 类:1package zyr.dp.cor;23public class OddSupport extends Support {45public OddSupport(String name) {6super(name);7 }89protected boolean resolve(Trouble trouble) {10return (trouble.getNumber()%2) == 1 ? true : false;11 }1213 }SpecialSupport 类:1package zyr.dp.cor;23public class SpecialSupport extends Support {45public int specialNumber;6public SpecialSupport(String name,int specialNumber) {7super(name);8this.specialNumber= specialNumber;9 }1011protected boolean resolve(Trouble trouble) {12return trouble.getNumber()==specialNumber ? true : false;13 }1415 }LimitSupport 类:1package zyr.dp.cor;23public class LimitSupport extends Support {45private int limit;6public LimitSupport(String name,int limit) {7super(name);8this.limit=limit;9 }1011protected boolean resolve(Trouble trouble) {12return trouble.getNumber()<=limit? true : false;13 }1415 }Main类:1package zyr.dp.cor;23public class Main {45public static void main(String[] args) {6 Support limitSupportLess = new LimitSupport("有限⽀持⼩",5);7 Support limitSupportMore = new LimitSupport("有限⽀持⼤",15);8 Support oddSupport = new OddSupport("奇数⽀持");9 Support specialSupport = new SpecialSupport("特定⽀持",36);10 Support noSupport = new NoSupport("没有⽀持");11 limitSupportLess.setAndReturnNext(limitSupportMore).setAndReturnNext(oddSupport).setAndReturnNext(specialSupport).setAndReturnNext(noSupport);12 System.out.println("===<有限⽀持⼩>尝试解决问题===");13for(int i=0;i<40;i++){14 limitSupportLess.support(new Trouble(i));15 }16 System.out.println("===<特定⽀持>尝试解决问题===");17for(int i=0;i<40;i++){18 specialSupport.support(new Trouble(i));19 }2021 }2223 }运⾏结果:1 ===<有限⽀持⼩>尝试解决问题===2对象:<有限⽀持⼩>已经解决问题,问题编号:[0]3对象:<有限⽀持⼩>已经解决问题,问题编号:[1]4对象:<有限⽀持⼩>已经解决问题,问题编号:[2]5对象:<有限⽀持⼩>已经解决问题,问题编号:[3]6对象:<有限⽀持⼩>已经解决问题,问题编号:[4]7对象:<有限⽀持⼩>已经解决问题,问题编号:[5]8对象:<有限⽀持⼤>已经解决问题,问题编号:[6]9对象:<有限⽀持⼤>已经解决问题,问题编号:[7]10对象:<有限⽀持⼤>已经解决问题,问题编号:[8]10对象:<有限⽀持⼤>已经解决问题,问题编号:[8]11对象:<有限⽀持⼤>已经解决问题,问题编号:[9]12对象:<有限⽀持⼤>已经解决问题,问题编号:[10]13对象:<有限⽀持⼤>已经解决问题,问题编号:[11]14对象:<有限⽀持⼤>已经解决问题,问题编号:[12]15对象:<有限⽀持⼤>已经解决问题,问题编号:[13]16对象:<有限⽀持⼤>已经解决问题,问题编号:[14]17对象:<有限⽀持⼤>已经解决问题,问题编号:[15]18对象:<没有⽀持>解决问题失败,问题编号:[16]19对象:<奇数⽀持>已经解决问题,问题编号:[17]20对象:<没有⽀持>解决问题失败,问题编号:[18]21对象:<奇数⽀持>已经解决问题,问题编号:[19]22对象:<没有⽀持>解决问题失败,问题编号:[20]23对象:<奇数⽀持>已经解决问题,问题编号:[21]24对象:<没有⽀持>解决问题失败,问题编号:[22]25对象:<奇数⽀持>已经解决问题,问题编号:[23]26对象:<没有⽀持>解决问题失败,问题编号:[24]27对象:<奇数⽀持>已经解决问题,问题编号:[25]28对象:<没有⽀持>解决问题失败,问题编号:[26]29对象:<奇数⽀持>已经解决问题,问题编号:[27]30对象:<没有⽀持>解决问题失败,问题编号:[28]31对象:<奇数⽀持>已经解决问题,问题编号:[29]32对象:<没有⽀持>解决问题失败,问题编号:[30]33对象:<奇数⽀持>已经解决问题,问题编号:[31]34对象:<没有⽀持>解决问题失败,问题编号:[32]35对象:<奇数⽀持>已经解决问题,问题编号:[33]36对象:<没有⽀持>解决问题失败,问题编号:[34]37对象:<奇数⽀持>已经解决问题,问题编号:[35]38对象:<特定⽀持>已经解决问题,问题编号:[36]39对象:<奇数⽀持>已经解决问题,问题编号:[37]40对象:<没有⽀持>解决问题失败,问题编号:[38]41对象:<奇数⽀持>已经解决问题,问题编号:[39]42 ===<特定⽀持>尝试解决问题===43对象:<没有⽀持>解决问题失败,问题编号:[0]44对象:<没有⽀持>解决问题失败,问题编号:[1]45对象:<没有⽀持>解决问题失败,问题编号:[2]46对象:<没有⽀持>解决问题失败,问题编号:[3]47对象:<没有⽀持>解决问题失败,问题编号:[4]48对象:<没有⽀持>解决问题失败,问题编号:[5]49对象:<没有⽀持>解决问题失败,问题编号:[6]50对象:<没有⽀持>解决问题失败,问题编号:[7]51对象:<没有⽀持>解决问题失败,问题编号:[8]52对象:<没有⽀持>解决问题失败,问题编号:[9]53对象:<没有⽀持>解决问题失败,问题编号:[10]54对象:<没有⽀持>解决问题失败,问题编号:[11]55对象:<没有⽀持>解决问题失败,问题编号:[12]56对象:<没有⽀持>解决问题失败,问题编号:[13]57对象:<没有⽀持>解决问题失败,问题编号:[14]58对象:<没有⽀持>解决问题失败,问题编号:[15]59对象:<没有⽀持>解决问题失败,问题编号:[16]60对象:<没有⽀持>解决问题失败,问题编号:[17]61对象:<没有⽀持>解决问题失败,问题编号:[18]62对象:<没有⽀持>解决问题失败,问题编号:[19]63对象:<没有⽀持>解决问题失败,问题编号:[20]64对象:<没有⽀持>解决问题失败,问题编号:[21]65对象:<没有⽀持>解决问题失败,问题编号:[22]66对象:<没有⽀持>解决问题失败,问题编号:[23]67对象:<没有⽀持>解决问题失败,问题编号:[24]68对象:<没有⽀持>解决问题失败,问题编号:[25]69对象:<没有⽀持>解决问题失败,问题编号:[26]70对象:<没有⽀持>解决问题失败,问题编号:[27]71对象:<没有⽀持>解决问题失败,问题编号:[28]72对象:<没有⽀持>解决问题失败,问题编号:[29]73对象:<没有⽀持>解决问题失败,问题编号:[30]74对象:<没有⽀持>解决问题失败,问题编号:[31]75对象:<没有⽀持>解决问题失败,问题编号:[32]76对象:<没有⽀持>解决问题失败,问题编号:[33]77对象:<没有⽀持>解决问题失败,问题编号:[34]78对象:<没有⽀持>解决问题失败,问题编号:[35]79对象:<特定⽀持>已经解决问题,问题编号:[36]80对象:<没有⽀持>解决问题失败,问题编号:[37]81对象:<没有⽀持>解决问题失败,问题编号:[38]82对象:<没有⽀持>解决问题失败,问题编号:[39]运⾏结果我们可以看到同等级的对象,按照⾃⼰被添加的次序来安排,这点⾮常重要,在实际应⽤中,我们都是将解答能⼒最弱的类放到最前⾯,然后⼀点点加强,这样可以使得解答能⼒⽐较弱的类有机会去解答,正如我们的例⼦,如果让解答能⼒强的类直接去处理问题,能够处理就不回传给下⼀个了,当然我们也看到这⾥⾯有的类能⼒有限,有的类和其他类的能⼒有重叠部分,当然也有所有类都解决不了的问题。
责任链模式什么是职责链模式使多个对象都有机会处理请求。
从⽽避免请求的发送者和接受者之前的耦合关系。
将这个对象连成⼀条链,并沿着这条链传递该请求,直到有⼀个对象处理它为⽌。
职责链模式的重⼼是在“链”上,由⼀条链去处理相似的请求在链中决定谁来处理这个请求,并返回对应的结果。
通⽤类图Handler:抽象处理者。
⼀是定义⼀个请求的处理⽅法handleMessage,唯⼀对外开放的⽅法。
⽽是定义⼀个链的编排⽅法setNext,设置下⼀个处理者;三是定义了详细的请求者必须实现的两个⽅法:定义⾃⼰可以处理的级别getHandlerLevel和详细的处理任务。
Client类:对责任模式进⾏封装,直接返回链中的第⼀个处理者。
详细链的设置不须要⾼层次模块关系,这样降低模块间的耦合,提⾼系统的灵活性。
通⽤代码abstract class Handler{protected Handler successor;public void SetSuccessor(Handler successor){this.successor = successor;}public abstract void HandleRequest(int request);}class ConcreteHandler1 : Handler{public override void HandleRequest(int request){if (request >= 0 && request < 10){Console.WriteLine("{0} 处理请求 {1}",this.GetType().Name, request);}else if (successor != null){successor.HandleRequest(request);}}}class ConcreteHandler2 : Handler{public override void HandleRequest(int request){if (request >= 10 && request < 20){Console.WriteLine("{0} 处理请求 {1}",this.GetType().Name, request);}else if (successor != null){successor.HandleRequest(request);}}}class ConcreteHandler3 : Handler{public override void HandleRequest(int request){if (request >= 20 && request < 30){Console.WriteLine("{0} 处理请求 {1}",this.GetType().Name, request);}else if (successor != null){successor.HandleRequest(request);}}}⽜⼑⼩试在此以机房收费系统学⽣下机计算消费⾦额为例,来实现职责链模式。
Chain of Responsibility(职责链模式)Chain of Responsibility(职责链模式)属于行为型模式。
行为型模式不仅描述对象或类的模式,还描述它们之间的通信模式,比如对操作的处理应该如何传递等等。
意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
几乎所有设计模式,在了解到它之前,笔者就已经在实战中遇到过了,因此设计模式的确是从实践中得出的真知。
但另一方面,如果没有实战的理解,单看设计模式是枯燥的,而且难以理解的,因此大家学习设计模式时,要结合实际问题思考。
举例子如果看不懂上面的意图介绍,没有关系,设计模式需要在日常工作里用起来,结合例子可以加深你的理解,下面我准备了三个例子,让你体会什么场景下会用到这种设计模式。
中间件机制设想我们要为一个后端框架实现中间件(知道 Koa 的同学可以理解为 Koa 的洋葱模型),在代码中可以插入任意多个中间件,每个中间件都可以对请求与响应进行处理。
由于每个中间件只响应自己感兴趣的请求,因此只有运行时才知道这个中间件是否会处理请求,那么中间件机制应该如何设计,才能保证其功能和灵活性呢?通用帮助文案如果一个大型系统中,任何一个模块点击都会弹出帮助文案,但并不是每个模块都有帮助文案的,如果一个模块没有帮助文案,则显示其父级的帮助文案,如果再没有,就继续冒泡到整个应用,展示应用级别的兜底帮助文案。
这种系统应该如何设计?JS 事件冒泡机制其实 JS 事件冒泡机制就是个典型的职责链模式,因为任何 DOM 元素都可以监听比如onClick,不仅可以自己响应事件,还可以使用event.stopPropagation()阻止继续冒泡。
意图解释JS 事件冒泡机制对前端来说太常见了,但我们换个角度,站在点击事件的角度理解,就能重新发现其设计的精妙之处:点击事件是叠加在每层 dom 上的,由于 dom 对事件的处理和绑定是动态的,浏览器本身不知道哪些地方会处理点击事件,但又要让每层 dom 拥有对点击事件的“平等处理权”,所以就产生了冒泡机制,与事件阻止冒泡功能。
设计模式--责任链模式简介责任链模式(Chain of Responsibility Pattern)也叫职责链模式:是将链中每⼀个节点看作是⼀个对象,每个节点处理的请求均不同,且内部⾃动维护⼀个下⼀节点对象。
当⼀个请求从链式的⾸端发出时,会沿着链的路径依次传递给每⼀个节点对象,知道有对象处理这个请求为⽌。
属于⾏为型模式。
责任链的应⽤场景1、⼯作中的审批流程2、游戏中的闯关责任链模式主要是解耦了请求与处理,客户只需将请求发送到链上即可,⽆需关⼼请求的具体内容和处理细节,请求会⾃动进⾏传递直⾄有节点对象进⾏处理。
适⽤于以下应⽤场景:1、多个对象可以处理同⼀请求,但具体由哪个对象处理则在运⾏时动态决定;2、在不明确指定接受者的情况下,向多个对象中的⼀个提交⼀个请求3、可动态指定⼀组对象处理请求责任链模式的UML类图:从UML类图,我们可以看到,责任链模式只要包含两种⾓⾊:抽象处理者(Handler):定义⼀个请求处理的⽅法,并维护⼀个下⼀个处理节点Handler对象的引⽤;具体处理者(ConcreteHandler):对请求进⾏处理,如果不感兴趣,则进⾏转发。
责任链模式的本质是解耦请求与处理,让请求在处理链中能进⾏传递与被处理;理解责任链模式应当理解的是其模式⽽不是具体实现,责任链模式的独到之处是其将节点处理者组成了链式结构,并允许节点⾃⾝决定是否进⾏请求处理或转发,相当于让请求流动了起来。
责任链模式在源码中的体现1、JDK中的应⽤,Filter类public interface Filter {public default void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException;public default void destroy() {}}这个接⼝相当于责任链模型中的Handler抽象⾓⾊。
通俗易懂系列设计模式(六):责任链模式责任链设计模式是⾏为设计模式之⼀。
责任链模式⽤于在软件设计中实现松散耦合,其中来⾃客户端的请求被传递到对象链以处理它们。
然后链中的对象将⾃⼰决定谁将处理请求以及是否需要将请求发送到链中的下⼀个对象。
JDK中的责任链模式⽰例让我们看⼀下JDK中责任链模式的例⼦,然后我们将继续实现这种模式的真实例⼦。
我们知道在try-catch块代码中我们可以有多个catch块。
这⾥每个catch块都是处理该特定异常的处理器。
因此当try块中发⽣任何异常时,它会发送到第⼀个catch块进⾏处理。
如果catch块⽆法处理它,它会将请求转发到链中的下⼀个对象,即下⼀个catch块。
如果即使最后⼀个catch块也⽆法处理它,那么异常将被抛出链接到调⽤程序。
责任链设计模式⽰例责任链模式的⼀个很好的例⼦是ATM分配机器。
⽤户按照定义的货币账单输⼊要分配的⾦额和机器分配⾦额,例如50美元,20美元,10美元等。
如果⽤户输⼊的数量不是10的倍数,则会引发错误。
我们将使⽤Chain of Responsibility模式来实现此解决⽅案。
链将以与下图相同的顺序处理请求。
请注意,我们可以在单应⽤程序中轻松实现此解决⽅案,但随后复杂性将增加,解决⽅案将紧密耦合。
因此,我们将创建⼀系列分配系统,以分配50美元,20美元和10美元的账单。
责任链设计模式 - 基类和接⼝我们可以创建⼀个类Currency来存储分配和链实现使⽤的数量。
Currency.javapackage com.journaldev.design.chainofresponsibility;public class Currency {private int amount;public Currency(int amt){this.amount=amt;}public int getAmount(){return this.amount;}}基接⼝应该有⼀个⽅法来定义链中的下⼀个处理器以及处理请求的⽅法。
1.1跟我学软件系统表示层的模块设计中所涉及的J2EE核心设计模式——责任链模式1.1.1责任链(Chain of Responsibility)模式1、什么是责任链模式(1)定义通过给一个以上对象处理请求的机会来避免请求的发送者和接收者的耦合---将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
因为这些类程序之间是一个松散的耦合,唯一的共同点是在他们之间传递请求。
也就是说,来了一个请求,A类的程序先处理,如果没有处理的话,就传递到B类程序来处理,如果还没有被处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。
责任链模式就是这种“推卸”责任的模式,你的问题在我这里能解决我就解决,不行就把你推给另一个对象。
(2)主要的技术特点1)在责任链模式中,很多对象由每一个对象对其下家的对象的引用而接起来形成一条链。
请求在这个链上传递,直到链上的某一个对象决定处理此请求。
2)客户并不需要知道链上的哪一个对象最终处理了这个请求,系统可以在不影响客户端的情况下动态的重新组织该链和分配链上的节点程序类的责任(功能)。
2、责任链模式基本的要求责任链上的处理者程序可以有两个选择:承担责任(完成处理功能)或者把责任推给下家(不进行功能处理)。
注意:一个请求可能最终没有被责任链上的任何处理者进行处理。
3、为什么会产生责任链模式1)通常,对节点的链式判断都喜欢使用过程语法if...elseif...else或者更加形象化的switch-case语法。
2)但如果接收对象对于开发者来说是未知的,我们就无法将其过程化,还必须借助面向对象的强大的扩展能力。
3)最常见的应用就是Filter(过滤器),是责任链模式的一种应用。
4、责任链模式在本项目中的具体应用示例本项目中的各个过滤器采用责任链模式,从而实现将各个过滤器串接起来以实现多级过滤效果。
public interface Filter{public void doFilter(final ServletRequest request,final ServletResponse response,FilterChain chain)throws IOException,ServletException;}public class UserAccessFilter implements Filter{public void doFilter(final ServletRequest request,final ServletResponse response,FilterChain chain)throws IOException,ServletException{ // 主要的功能方法的实现chain.doFilter(request,response); //转向下一个过滤器}5、责任链模式的主要优缺点如果每个接收对象都需要处理请求的某一部分,就可以将不同的处理功能放在不同的对象里面,对单一处理的改动也非常方便。
Java设计模式——责任链模式设计模式⽂章概述顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了⼀个接收者对象的链。
这种模式给予请求的类型,对请求的发送者和接收者进⾏解耦。
这种类型的设计模式属于⾏为型模式。
在这种模式中,通常每个接收者都包含对另⼀个接收者的引⽤。
如果⼀个对象不能处理该请求,那么它会把相同的请求传给下⼀个接收者,依此类推。
在现实⽣活中,常常会出现这样的事例:⼀个请求有多个对象可以处理,但每个对象的处理条件或权限不同。
例如,公司员⼯请假,可批假的领导有部门负责⼈、副总经理、总经理等,但每个领导能批准的天数不同,员⼯必须根据⾃⼰要请假的天数去找不同的领导签名,也就是说员⼯必须记住每个领导的姓名、电话和地址等信息,这增加了难度。
这样的例⼦还有很多,如找领导出差报销、⽣活中的“击⿎传花”游戏等。
在计算机软硬件中也有相关例⼦,如总线⽹中数据报传送,每台计算机根据⽬标地址是否同⾃⼰的地址相同来决定是否接收;还有异常处理中,处理程序根据异常的类型决定⾃⼰是否处理该异常;还有的拦截器、和的 Filter 等,所有这些,如果⽤责任链模式都能很好解决。
模式的定义与特点责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在⼀起,将所有请求的处理者通过前⼀对象记住其下⼀个对象的引⽤⽽连成⼀条链;当有请求发⽣时,可将请求沿着这条链传递,直到有对象处理它为⽌。
注意:责任链模式也叫职责链模式。
在责任链模式中,客户只需要将请求发送到责任链上即可,⽆须关⼼请求的处理细节和请求的传递过程,所以责任链将请求的发送者和请求的处理者解耦了。
责任链模式是⼀种对象⾏为型模式,其主要优点如下。
1. 降低了对象之间的耦合度。
该模式使得⼀个对象⽆须知道到底是哪⼀个对象处理其请求以及链的结构,发送者和接收者也⽆须拥有对⽅的明确信息。
2. 增强了系统的可扩展性。
设计模式10-策略模式与责任链模式详解1.10.策略模式与责任链模式详解1.10.1.策略模式详解时长:1h15min10.1.1.策略模式的定义定义: 策略模式【Strategy Pattern】,⼜叫政策模式【Policy Pattern】,它是将定义的算法家族,分别封装起来,让它们之间可以相互替换,从⽽让算法的变化不会影响到使⽤算法的⽤户。
可以避免多重分⽀的if...else...和switch语句。
属于⾏为型模式。
10.1.1.1.策略模式在⽣活中应⽤场景 阶梯个税【⼯资收⼊不同,个税算法不同】 移动⽀付⽅式选择【微信,⽀付宝,银联】 出⾏交通⽅式选择【⽕车,飞机,汽车,轮船】10.1.1.1、2.策略模式的应⽤场景1.假如系统中有很多类,⽽他们的区别仅仅在于他们的⾏为不同。
2.⼀个系统需要动态地在⼏种算法中选择⼀种。
3.需要屏蔽算法规则。
10.1.2.策略模式的通⽤实现10.1.2.1.类图设计10.1.2.2.代码实现1.顶层策略接⼝package com.wf.strategy.general;/*** @ClassName IStrategy* @Description 顶层策略接⼝* @Author wf* @Date 2020/6/18 10:11* @Version 1.0*/public interface IStrategy {/*** 算法接⼝*/void algorithm();}2.策略⼦类实现package com.wf.strategy.general;/*** @ClassName ConcreteStrategyA* @Description 具体策略⼦类A* @Author wf* @Date 2020/6/18 10:13* @Version 1.0*/public class ConcreteStrategyA implements IStrategy { @Overridepublic void algorithm() {System.out.println("这是算法A");}}package com.wf.strategy.general;/*** @ClassName ConcreteStrategyB* @Description 具体策略⼦类B* @Author wf* @Date 2020/6/18 10:13* @Version 1.0*/public class ConcreteStrategyB implements IStrategy { @Overridepublic void algorithm() {System.out.println("这是算法B");}}3.上下⽂对象package com.wf.strategy.general;/*** @ClassName Context* @Description 上下⽂对象* @Author wf* @Date 2020/6/18 10:14* @Version 1.0*/public class Context {private IStrategy strategy;public Context(IStrategy strategy) {this.strategy = strategy;}//由构造器中传参实现⼦类类型,来决定选择哪⼀种算法public void algorithm(){this.strategy.algorithm();}}4.测试类package com.wf.strategy.general;/*** @ClassName Test* @Description 测试类* @Author wf* @Date 2020/6/18 10:15* @Version 1.0*/public class Test {public static void main(String[] args) {//使⽤时,客户选择⼀种策略IStrategy strategy = new ConcreteStrategyA();//封装到上下⽂中Context context = new Context(strategy);//调⽤策略⽅法context.algorithm();}}测试结果如下:10.1.3.策略模式的实现⽰例之促销案例10.1.3.1.代码实现1.顶层接⼝package com.wf.strategy.demo.promotion;/*** @ClassName IPromotionStrategy* @Description 促销策略接⼝* @Author wf* @Date 2020/6/18 10:31* @Version 1.0*/public interface IPromotionStrategy {/*** 促销⽅法*/void doPromotion();}2.实现⼦类package com.wf.strategy.demo.promotion;/*** @ClassName GroupPurchaseStrategy* @Description 团购促销* @Author wf* @Date 2020/6/18 10:36* @Version 1.0*/public class GroupPurchaseStrategy implements IPromotionStrategy{ @Overridepublic void doPromotion() {System.out.println("5⼈成团,可以优惠");}}package com.wf.strategy.demo.promotion;/*** @ClassName CashRollbackStrategy* @Description 返现促销* @Author wf* @Date 2020/6/18 10:34* @Version 1.0*/public class CashRollbackStrategy implements IPromotionStrategy { @Overridepublic void doPromotion() {System.out.println("返现,直接打款到⽀付宝帐号");}}package com.wf.strategy.demo.promotion;/*** @ClassName CouponStrategy* @Description 优惠券促销⽅式* @Author wf* @Date 2020/6/18 10:33* @Version 1.0*/public class CouponStrategy implements IPromotionStrategy {@Overridepublic void doPromotion() {System.out.println("使⽤优惠券抵扣");}}package com.wf.strategy.demo.promotion;/*** @ClassName EmptyStrategy* @Description ⽆优惠购买* @Author wf* @Date 2020/6/18 10:37* @Version 1.0*/public class EmptyStrategy implements IPromotionStrategy {@Overridepublic void doPromotion() {System.out.println("原价购买,⽆优惠");}}3.测试类public static void main(String[] args) {String promotion = "";IPromotionStrategy strategy = null;if("团购".equals(promotion)){strategy = new GroupPurchaseStrategy();}else if("".equals(promotion)){//...strategy = new EmptyStrategy();}}测试结果:说明: 这⾥并没有使⽤策略模式,⽽是通过分⽀判断,多态的⽅式来实现。