解釋器模式express
解釋器模式就是定義一種語言,並定義這個語言的解釋器,解釋器可以按照定義好的語法來將這種語言‘翻譯’成使用者能理解的語言。數組
普遍上來說,Java是一種定義的語言,JVM就是一種‘解釋器’,而計算機就是最終的使用者。咱們寫一段Java代碼,而計算機只認識0101的機器語言,JVM就是將Java代碼解釋成0101的機器語言讓計算機可以理解並運行。ide
咱們仍是以咱們實驗室的實例來講明下這個模式。this
最近咱們實驗室的獸人工廠拿到了老總的一個批示:spa
class LaoZong { private String order = "MN1n2"; public String getOrder() { return order; } public void setOrder(String order) { this.order = order; } } class ShouRenFactory { public void readOrder() { LaoZong lz = new LaoZong(); System.out.println(lz.getOrder()); } } public class Interpreter { public static void main(String[] args) { new ShouRenFactory().readOrder(); } }
因而獸人工廠拿到老闆的指令就是"MN1n2"。徹底不明白要幹什麼,因而須要找老闆祕書來解釋下:翻譯
class ShouRenFactory { public void readOrder() { LaoZong lz = new LaoZong(); MiShu ms = new MiShu(); System.out.println(ms.translate(lz.getOrder())); } } class MiShu { public String translate(String order) { //Black Box String realWord = "生產男獸人1個女獸人2個"; return realWord; } }
如今咱們獸人工廠終於知道了老總的命令:"生產男獸人1個女獸人2個", 可是祕書是怎麼知道老總的命令的呢,若是獸人工廠也能知道祕書解析的過程,那就不用每次都麻煩祕書來解釋了。畢竟祕書是老闆用的,而不是獸人工廠用的。code
請教祕書解析的方法:blog
祕書說她先判斷每個字幕或者數組是什麼類型的命令,而後再用不一樣的解釋方法解釋不一樣的類型,好比說‘M’就是命令類的,‘Nn’是產品名稱類的,數字就是數量類的。get
因而獸人工廠就根據祕書的方法實現了本身的解析方式:產品
public class Interpreter { public static void main(String[] args) { new ShouRenFactory().readOrder(); } } class ShouRenFactory { private String translate(String order) { String realOrder = ""; //組裝解釋器 List<Expression> expressions = new ArrayList<Expression>(); expressions.add(new CommandExpression()); expressions.add(new ProductExpression()); expressions.add(new NumberExpression()); //挨個解釋老總的命令 String[] codes = order.split(""); for (String code :codes) { for (Expression expression : expressions) { if (expression.matches(code)) { realOrder += expression.excute(code); break; } } } return realOrder; } public void readOrder() { LaoZong lz = new LaoZong(); System.out.println(translate(lz.getOrder())); } } abstract class Expression { protected HashMap<String, String> map = new HashMap<String, String>(); private Set<String> getMarkers() { return map.keySet(); } public boolean matches(String code) { return getMarkers().contains(code); } abstract public String excute(String code); } class CommandExpression extends Expression { public CommandExpression() { map.put("M", "建立"); map.put("D", "銷燬"); map.put("E", "維修"); } @Override public String excute(String code) { return map.get(code); } } class ProductExpression extends Expression { public ProductExpression() { map.put("N", "男獸人"); map.put("n", "女獸人"); } @Override public String excute(String code) { return map.get(code); } } class NumberExpression extends Expression { public NumberExpression() { } @Override public boolean matches(String code) { return code.matches("[0-9]"); } @Override public String excute(String code) { return code + "個"; } }
這樣咱們就實現了一個簡單的解析器模式,在這種模式下,咱們能夠很簡單的增長或者刪除某種解析器。
解析器模式是一種易於理解但難於應用的模式。 除非在「一種特定類型的問題發生的頻率足夠高」的狀況下,咱們並不推薦使用此模式。由於當文法特別複雜時,會產生不少類,這對維護來講比較困難。總的來講在文法比較簡單且發生頻率很高的狀況下才使用此模式。