解釋器模式
摘要
本文通過簡潔的模式描述,應用場景的詳細代碼實現,以及匹配的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.