【設計模式 - 15】之解釋器模式(Interpreter)

1      模式簡介

解釋器模式允許我們自定義一種語言,並定義一個這種語言的解釋器,這個解釋器用來解釋語言中的句子。由於這種模式主要用於編譯器的編寫,因此在日常應用中不是很常用。

 

如果一種特定類型的問題發生頻率足夠高,那麼可能就值得將該問題的各個實例表述爲一種簡單語言中的一個句子,這樣就可以構建一個解釋器,該解釋器通過解釋這些句子來解決該問題。

 

解釋器模式的優點:

1)        可擴展性比較好,靈活;

2)        增加了新的解釋表達式的方式;

3)        易於實現簡單文法。

 

解釋器模式的缺點:

1)        可利用場景比較少;

2)        對於複雜的文法比較難維護;

3)        解釋器模式會引起類膨脹;

4)        解釋器模式採用遞歸調用方法。

 

解釋器模式的使用場景:

1)        可以將一個需要解釋執行的語言中的句子表示爲一個抽象語法樹;

2)        一些重複出現的問題可以用一種簡單的語言來進行表達;

3)        一個簡單語法需要解釋的場景。

 

2      案例

在本例中我們定義一個解釋器來解決日常的算數問題,如:(a + b) / (a - b + 6) * a。


具體代碼如下:

在解釋器模式中,每個操作或參數都可以被抽象成一個表達式,因此我們首先定義一個表達式抽象類Expression,代碼如下:

public abstract class Expression {
	protected String key;

	public String getKey() {
		return key;
	}

	public abstract Expression interpret(Context context);
}
變量表達式VariableExpression中的代碼:

public class VariableExpression extends Expression {
	private Integer value;

	public VariableExpression(String key, Integer value) {
		super.key = key;
		this.value = value;
	}

	public Integer getValue() {
		return value;
	}

	@Override
	public Expression interpret(Context context) {
		context.addVariable(super.key, value);
		return this;
	}
}
加減乘除表達式的代碼,這裏以除法表達式DivideExpression中的代碼爲例:

public class DivideExpression extends Expression {
	private String resultExpressionKey;
	private Expression leftExpression;
	private Expression rightExpression;

	public DivideExpression(String resultExpressionKey, Expression leftExpression, Expression rightExpression) {
		this.resultExpressionKey = resultExpressionKey;
		this.leftExpression = leftExpression;
		this.rightExpression = rightExpression;
	}

	@Override
	public Expression interpret(Context context) {
		Integer rightVariableValue = ((VariableExpression) rightExpression).getValue();
		if (rightVariableValue != 0) {
			return new VariableExpression(resultExpressionKey,
					((VariableExpression) leftExpression).getValue() / rightVariableValue);
		}
		return null;
	}
}
測試類Test中的代碼如下:

/**
 * 計算:(a + b) / (a - b + 6) * a
 */
public class Test {
	public static void main(String[] args) {
		// 上下文對象
		Context context = new Context();
		// 向上下文對象中添加變量
		VariableExpression a = (VariableExpression) new VariableExpression("a", 11).interpret(context);
		VariableExpression b = (VariableExpression) new VariableExpression("b", 10).interpret(context);
		VariableExpression c = new VariableExpression("c", 6);

		// 開始計算
		Expression tmpResult1 = new AddExpression("tmp1", a, b).interpret(context);
		Expression tmpResult2 = new MinusExpression("tmp2", a, b).interpret(context);
		Expression tmpResult3 = new AddExpression("tmp3", tmpResult2, c).interpret(context);
		Expression tmpResult4 = new DivideExpression("tmp4", tmpResult1, tmpResult3).interpret(context);
		Expression tmpResult5 = new MultiplyExpression("tmp5", tmpResult4, a).interpret(context);

		// 打印結果
		System.out.println("結果是:" + ((VariableExpression) tmpResult5).getValue());
	}
}
運行結果如下圖所示:



最後貼出解釋器模式在GitHub中的代碼地址:【GitHub - Interpreter】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章