行为型设计模式之解释器模式、命令模式和责任链模式
解释器模式(Interpreter Pattern)
定义:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.(给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。)
解释器模式类图:
- AbstractExpression——抽象解释器
具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和Non-terminalExpression完成。
- TerminalExpression——终结符表达式
实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是VarExpression类,表达式中的每个终结符都在栈中产生了一个VarExpression对象。
- NonterminalExpression——非终结符表达式
文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分别对应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
- Context——环境角色
具体到我们的例子中是采用HashMap代替。
使用场景:
- 重复发生的问题可以使用解释器模式
- 一个简单语法需要解释的场景
💡注意:
尽量不要在重要的模块中使用解释器模式,否则维护会是一个很大的问题。在项目中可以使用shell、JRuby、Groovy等脚本语言来代替解释器模式,弥补Java编译型语言的不足。
命令模式(Command Pattern)
定义:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)
命令模式类图:
- Receive接收者角色
该角色就是干活的角色,命令传递到这里是应该被执行的,具体到我们上面的例子中就是Group的三个实现类(需求组,美工组,代码组)。
- Command命令角色
需要执行的所有命令都在这里声明。
- Invoker调用者角色
接收到命令,并执行命令。在例子中,我(项目经理)就是这个角色。
使用场景:
认为是命令的地方就可以采用命令模式,例如,在GUI开发中,一个按钮的点击是一个命令,可以采用命令模式;模拟DOS命令的时候,当然也要采用命令模式;触发-反馈机制的处理等。
责任链模式(Chain of Responsibility Pattern)
定义:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)
责任链模式类图:
- Handler: 抽象处理者
- ConcreteHandler: 具体处理者
- Client: 客户类
抽象处理者的代码:
public abstract class Handler {
private Handler nextHandler;
//每个处理者都必须对请求做出处理
public final Response handleMessage(Request request) {
Response response = null;
//判断是否是自己的处理级别
if (this.getHandlerLevel().equals(request.getRequestLevel())) {
response = this.echo(request);
} else { //不属于自己的处理级别
//判断是否有下一个处理者
if (this.nextHandler != null) {
response = this.nextHandler.handleMessage(request);
} else {
//没有适当的处理者,业务自行处理
}
}
return response;
}
//设置下一个处理者是谁
public void setNext(Handler _handler) {
this.nextHandler = _handler;
}
//每个处理者都有一个处理级别
protected abstract Level getHandlerLevel();
//每个处理者都必须实现处理任务
protected abstract Response echo(Request request);
}
抽象的处理者实现三个职责:
一是定义一个请求的处理方法handleMessage,唯一对外开放的方法;
二是定义一个链的编排方法setNext,设置下一个处理者;
三是定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel和具体的处理任务echo。
💡注意事项:
链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。
本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位大佬指出。
保持热爱,奔赴下一场山海。🏃🏃🏃
- 点赞
- 收藏
- 关注作者
评论(0)