解释器模式
摘要
本文通过简洁的模式描述,应用场景的详细代码实现,以及匹配的UML,详解介绍了解释器模式的原理及应用。本文可帮助读者快速掌握解释器模式,以便工作学习中使用解释器模式。
一、解释器模式
在生活中,我们的某些行动所包含的步骤是随着当时的情况而定的,比如,一个行动本应该由步骤一、步骤二、步骤三组成,但特殊情况发生,现在这个行动只需要步骤一和步骤三即可完成,所以在这种情况下,不会去做步骤二。
在编程中,也存在类似的情况,一个操作需要三个步骤才能完成,但是该操作对于某对象只需要两个步骤,或是某些对象需要四个步骤。所以“步骤”与“操作”之间存在变化关系,如果将“步骤”与“操作”写死,会导致一个操作有多个实现,违背了“开闭原则”。
解释器模式是将每一个“步骤”抽象出来,单独成为一个类,并加入到一个具有存储“步骤”的容器类中。每一个“操作”类,直接对接“步骤”容器类,并从容器中获取每个“操作”类所需的“步骤”进行处理。“步骤”类与“操作”类继承于同一个父类(解释器抽象类),重写该父类的“处理”函数,“步骤”类的“处理”函数则是表明该单一步骤所进行的处理动作,而“操作”类的“处理”函数则是表明该不同情况的“操作”具体类所进行的各步骤处理动作。
二、解释器模式的实现
2.1 场景设计
现在有跑步运动,原本该运动的步骤有四步,但是Tom只操作了第一步和第二步,而Damon只操作了第三步和第四步。
2.2 代码实现
2.2.1 Expression 解释器抽象类
package ft.patterns.expression;
public interface Expression {
public String handle(Context context);
}
2.2.2 ExpressionValue “步骤”具体类
package ft.patterns.expression;
public class ExpressionValue implements Expression{
private String name;
public ExpressionValue(String name) {
this.name = name;
}
@Override
public String handle(Context context) {
return context.getExpression(this);
}
}
2.2.3 ExpressionOption “操作” 解释器抽象类
package ft.patterns.expression;
public abstract class ExpressionOption implements Expression{
protected Expression one;
protected Expression two;
public ExpressionOption(Expression one, Expression two) {
this.one = one;
this.two = two;
}
}
2.2.4 TomRun “操作”解释器具体类
package ft.patterns.expression;
public class TomRun extends ExpressionOption{
TomRun(Expression one, Expression two){
super(one, two);
}
@Override
public String handle(Context context) {
return this.one.handle(context) +"\n"+ this.two.handle(context);
}
}
2.2.5 DamonRun “操作”解释器具体类
package ft.patterns.expression;
public class DamonRun extends ExpressionOption{
DamonRun(Expression one, Expression two){
super(one, two);
}
@Override
public String handle(Context context) {
return this.one.handle(context) +"\n"+ this.two.handle(context);
}
}
2.2.6 Context “步骤”容器类
package ft.patterns.expression;
import java.util.HashMap;
import java.util.Map;
public class Context {
Map<Expression, String> valueMap;
Context(){
valueMap = new HashMap<Expression, String>();
}
public void addExpression(Expression name, String value) {
valueMap.put(name, value);
}
public String getExpression(Expression name) {
return valueMap.get(name);
}
}
2.2.7 Main 测试类
package ft.patterns.expression;
public class Main {
public static void main(String[] args) {
Context context = new Context();
Expression runStep01 = new ExpressionValue("run1");
Expression runStep02 = new ExpressionValue("run2");
context.addExpression(runStep01, "step one of Run method.");
context.addExpression(runStep02, "step two of Run method.");
Expression runStep03 = new ExpressionValue("run3");
Expression runStep04 = new ExpressionValue("run4");
context.addExpression(runStep03, "step three of Run method.");
context.addExpression(runStep04, "step four of Run method.");
TomRun tomRun = new TomRun(runStep01, runStep02);
System.out.println(tomRun.handle(context));
System.out.println();
DamonRun damonRun = new DamonRun(runStep03, runStep04);
System.out.println(damonRun.handle(context));
}
}
2.2.8 测试结果
step one of Run method.
step two of Run method.
step three of Run method.
step four of Run method.