源碼git地址 https://github.com/dlovetco/designMode
有時候我們會遇到這樣的一個問題:客戶端能夠提供的參數並不是我們所需要的。在調用正確的api之前,我們需要先把客戶端傳進來的參數解析成我們所需要的格式。
問題的提出
音樂簡譜中描繪樂曲用的是1234567,而實際發出的聲音卻是“哆瑞咪發嗦啦西”。實現一個簡譜到音樂的轉譯系統。
解釋器模式
給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
package interpretermode;
import java.util.Arrays;
public class InterpreterMode {
public static void main(String[] args) {
Context context = new Context();
context.setText("1 2 3 4 5 6 7");
Expression note = new Note();
note.execute(context);
}
}
/**
* 文法表達式接口
*/
interface Expression {
void execute(Context context);
}
/**
* 音符類 進行具體的音符轉換
*/
class Note implements Expression {
@Override
public void execute(Context context) {
String[] keys = context.getText().split(" ");
Arrays.stream(keys).forEach(key -> {
switch (key) {
case "1":
System.out.println("do");
break;
case "2":
System.out.println("re");
break;
case "3":
System.out.println("mi");
break;
case "4":
System.out.println("fa");
break;
case "5":
System.out.println("so");
break;
case "6":
System.out.println("la");
break;
case "7":
System.out.println("xi");
break;
}
});
}
}
/**
* 待解釋的文本
*/
class Context {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
我這邊寫的例子比較簡單,解釋器的子類只寫了一個。複雜一點的話可以寫多個文法解釋類,然後在客戶端根據條件實例化不同的子類進行解釋。
使用瞭解釋器模式就意味着可以很容易地改變和擴展文法,因爲該模式使用類來表示文法規則,你可使用繼承來改變或擴展該文法。
解釋器模式不足的地方在於:解釋器模式爲文法中的每一條規則至少定義了一個類,因此包含許多規則的文法可能難以管理和維護。
plantuml
@startuml
interface Expression{
{abstract}execute(Context context)
}
Expression <|.. Note
class Note{
execute(Context context)
}
Context <.. Expression
class Context{
string text
}
@enduml