大話設計模式讀書筆記(直譯器模式)
人物:大鳥,小菜
事件:小菜給大鳥說領導找他談話,說他工作不錯,說另一個同事梅星工作一般,大鳥說小菜沒有領會到領導的言外之意,其實領導是側面告訴小菜,你乾的不錯,後面可能需要你多加加油,工作量可能提一提,而同事梅星工作一般,可能領導對他不是很滿意。小菜覺得職場太複雜要是有個翻譯器就好了,大鳥順之引出瞭解釋器模式。
直譯器模式:
1.介紹瞭解釋器模式的概念
2.結構圖
3.直譯器模式程式碼
4.好處與不足
5.小結
直譯器模式
1.概念:給定一個語言(巫師世界的語言),定義它的文法的一種表示(麻瓜),並定義一個直譯器(羅納德·比利爾斯·韋斯萊),這個直譯器使用該表示來解釋言語中的句子(不懂魔法的人類)
2.結構圖:
注:
(1)終結符:終結符直接就代表一個意思,是不可拆分的最小元素,比如關鍵字if就不能再分成i和f了。
(2)非終結符:非終結符可以再分成更細的東西,且不是終結符的都是非終結符。
3.程式碼示意:
前情提要:
(1)什麼是語法樹:是原始碼的抽象語法結構的樹狀表現形式
(2)舉例:foo = 'hello world';
AbstractExpression類,宣告一個抽象的解釋操作,這個介面為抽象語法樹共享:
public abstract class AbstractExpression { public abstract void interpret(Context context); }
TerminalExpression類,實現抽象表示式中所有介面,主要是一個interpret方法,文中每一個終結符都有一個具體終結表示式與之對應:
@Slf4j public class TerminalExpression extends AbstractExpression { @Override public void interpret(Context context) { log.info("終端直譯器"); } }
NonterminalExpressionl類,非終結符表示式,為文中非終結符實現解釋操作:
@Slf4j publicclass NonterminalExpression extends AbstractExpression { @Override public void interpret(Context context) { log.info("非終端直譯器"); } }
Context類,包含直譯器之外的一些全域性資訊:
@Data public class Context { private String input; private String output; }
客戶端程式碼,構建表示該文法定義的語言中一個特定的句子的抽象語法樹,呼叫解釋操作:
public class ExpressionClient { public static void main(String[] args) { Context context = new Context(); List<AbstractExpression> list = new ArrayList<>(); list.add(new TerminalExpression()); list.add(new NonterminalExpression()); list.add(new TerminalExpression()); list.add(new TerminalExpression()); for (AbstractExpression exp : list) { exp.interpret(context); } } }
4.好處:用直譯器模式,意味著很容易地改變和擴充套件文法(即語法),因為該模式使用類來標識文法規則,你可以使用繼承來改變或擴充套件該文法,也比較容易實現文法,因為定義抽象語法樹中各節點的類的實現大體類似,這些類都易於直接編寫。
不足:直譯器模式為文法中的每一條規則至少定義了一個類,因此包含許多規則的文法可能難以管理和維護。所以建議當文法複雜時,使用其他程式如語法分析程式或編譯器生成器來處理。
5.小結:直譯器模式就是把一串可能看不懂的字串,通過一系列規則,轉化成看得懂的資訊,或者是把我們常用的資訊,通過規則轉化,轉成機器或者程式碼看得懂的指令。