編輯:關於Android編程
這篇博客我們來介紹一下解釋器模式(Interpreter Pattern),也是行為型設計模式之一,是一種用的比較少的設計模式,其提供了一種解釋語言的語法或表達式的方式,該模式定義了一個表達式接口,通過該接口解釋一個特定的上下文。在這麼多的設計模式中,解釋器模式在實際運用上相對來說要少很多,因為我們很少會去構造一個語言的文法。雖然你幾乎用不到這個模式,但是看一看還是能受到一定的啟發的。
給定一個語言,定義它的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中的句子。
該模式的使用場景相當廣泛,總的概括下來大概有以下幾種:
我們來看看解釋器模式的 uml 類圖:
vcfJq6O6PC9wPg0KQWJzdHJhY3RFeHByZXNzaW9uo7qz6c/zse2078q9yfnD99K7uPaz6c/ztcS94srNstnX97i4wOCjrLKitqjS5dK7uPaz6c/ztcQgaW50ZXJwcmV0KCkgveLKzbe9t6ijrMbkvt/M5bXEyrXP1tTauPe49r7fzOW1xNfTwOC94srNxvfW0M3qs8mho1Rlcm1pbmFsRXhwcmVzc2lvbqO61tW94bf7se2078q9yrXP1sHLs+nP87HttO/Kvb3HyavL+dKqx/O1xL3Tv9qjrNb30qrKx9K7uPZpbnRlcnByZXQoKbe9t6iju87Et6jW0LXEw7/Su7j21tW94bf7trzT0NK7uPa+38zl1tW94bHttO/KvdPr1q7P4LbU06aho7HIyOfT0NK7uPa88rWltcS5q8q9Uj1SMStSMqOs1NrA78PmUjG6zVIyvs3Kx9bVveG3+6OsttTTprXEveLO9lIxus1SMrXEveLKzcb3vs3Kx9bVveG3+7HttO/KvaGjTm9udGVybWluYWxFeHByZXNzaW9uo7q3x9bVveG3+7HttO/Kvc7Et6jW0LXEw7/Su8z1uebU8ra80OjSqtK7uPa+38zltcS3x9bVveG3+7HttO/KvaOst8fW1b3ht/ux7bTvyr3Su7DjysfOxLeo1tC1xNTLy+O3+7vy1d/G5Mv7udi8/NfWo6yxyMjnuavKvVI9UjErUjLW0KOsJmxkcXVvOysmcmRxdW87vs3Kx7fH1tW94bf7o6y94s72JmxkcXVvOysmcmRxdW87tcS94srNxve+zcrH0ru49rfH1tW94bf7se2078q9oaNDb250ZXh0o7rJz8/CzsS7t76zwODV4rj2vcfJq7XEyM7O8dK7sOPKx9PDwLS05rfFzsS3qNbQuPe49tbVveG3+8v5ttTTprXEvt/M5da1o6yxyMjnUj1SMStSMqOsztLDx7j4UjG4s9a1MTAwo6y4+FIyuLPWtTIwMKGj1eLQqdDFz6LQ6NKqtOa3xbW9u7e+s73HyavW0KOsuty24Mfpv/bPws7Sw8fKudPDTWFwwLSz5LWxu7e+s73Hyau+zdfjubvBy6GjQ2xpZW50o7q/zbunwOC94s72se2078q9o6y5ub2os+nP89Pvt6jK96Os1rTQ0L7fzOW1xL3iys2y2df3tciho6GhoaHNqNPDtPrC68jnz8Kjug0KPHA+Jm5ic3A7PC9wPg0KPHByZSBjbGFzcz0="brush:java;">
public abstract class AbstractExpression {
/**
* 抽象的解析方法
* @param context 上下文環境對象
*/
public abstract void interpret(Context context);
}
public class TerminalExpression extends AbstractExpression{
@Override
public void interpret(Context context) {
//實現文法中與終結符有關的解釋操作
}
}
public class NonterminalExpression extends AbstractExpression{
@Override
public void interpret(Context context) {
//實現文法中與非終結符有關的解釋操作
}
}
public class Context {
}
public class Client {
public static void main(String[] args) {
//根據文法對特定句子構建抽象語法樹後解釋
}
}
為了說明解釋器模式的實現辦法,這裡就以 wiki 上的算術表達式的解釋為例,如表達式“m + n + p”,如果我們使用解釋器模式對該表達式進行解釋,那麼代表數字的 m、n 和 p 三個字母我們就可以看成是終結符號,而“+”這個算術運算符號則可當作非終結符號。這個簡單的文法如下:
expression ::= plus | minus | variable | number plus ::= expression expression '+' minus ::= expression expression '-' variable ::= 'a' | 'b' | 'c' | ... | 'z' digit ::= '0' | '1' | ... | '9' number ::= digit | digit number
定義一個包含逆波蘭表達式的語言:
a b + a b c + - a b + c a - -
於是根據上面的語言和文法,我們可以簡單寫出下面的示例:
AbstractExpression,TerminalExpression,NonterminalExpression:
import java.util.Map; interface Expression { public int interpret(Mapvariables); } class Number implements Expression { private int number; public Number(int number) { this.number = number; } public int interpret(Map variables) { return number; } } class Plus implements Expression { Expression leftOperand; Expression rightOperand; public Plus(Expression left, Expression right) { leftOperand = left; rightOperand = right; } public int interpret(Map variables) { return leftOperand.interpret(variables) + rightOperand.interpret(variables); } } class Minus implements Expression { Expression leftOperand; Expression rightOperand; public Minus(Expression left, Expression right) { leftOperand = left; rightOperand = right; } public int interpret(Map variables) { return leftOperand.interpret(variables) - rightOperand.interpret(variables); } } class Variable implements Expression { private String name; public Variable(String name) { this.name = name; } public int interpret(Map variables) { if(null==variables.get(name)) return 0; //Either return new Number(0). return variables.get(name).interpret(variables); } }
Context
import java.util.Map; import java.util.Stack; class Evaluator { private Expression syntaxTree; public Evaluator(String expression) { StackexpressionStack = new Stack (); for (String token : expression.split(" ")) { if (token.equals("+")) { Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop()); expressionStack.push( subExpression ); } else if (token.equals("-")) { // it's necessary remove first the right operand from the stack Expression right = expressionStack.pop(); // ..and after the left one Expression left = expressionStack.pop(); Expression subExpression = new Minus(left, right); expressionStack.push( subExpression ); } else expressionStack.push( new Variable(token) ); } syntaxTree = expressionStack.pop(); } public int calculate(Map context) { return syntaxTree.interpret(context); } }
Client
import java.util.Map; import java.util.HashMap; public class InterpreterExample { public static void main(String[] args) { String expression = "w x z - +"; Evaluator sentence = new Evaluator(expression); Mapvariables = new HashMap (); variables.put("w", new Number(5)); variables.put("x", new Number(10)); variables.put("z", new Number(42)); int result = sentence.calculate(variables); System.out.println(result); } }
解釋器模式的優點是其靈活的擴展性,當我們想對文法規則進行擴展延伸時,只需要增加相應的非終結符解釋器,並在構建抽象語法樹時,使用到新增的解釋器對象進行具體的解釋即可,非常方便。
解釋器模式的缺點也顯而易見,因為對於每一條文法都可以對應至少一個解釋器,其會生成大量的類,導致後期維護困難;同時,對於過於復雜的文法,構建其抽象語法樹會顯得異常繁瑣,甚至有可能會出現需要構建多棵抽象語法樹的情況,因此,對於復雜的文法並不推薦使用解釋器模式。
https://github.com/zhaozepeng/Design-Patterns/tree/master/InterpreterPattern
Tomcat的結構很復雜,但是Tomcat也非常的模塊化,找到了Tomcat最核心的模塊,就抓住了Tomcat的“七寸”。整體結構Tomcat 總
主要包括那些不錯的開發庫,包括依賴注入框架、圖片緩存、網絡相關、數據庫ORM建模、Android公共庫、Android 高版本向低版本兼容、多媒體相關及其他。一、依賴注入
程序主要有兩個功能,一是護眼燈,二是手電筒,然而手電筒兼容性解決辦法就是加入異常控制,避免各種異常占用啟動不了手電筒.程序主界面,沒有美化,只實現基本功能.部分代碼:護眼
菜單策劃:原理:使用控件繼承HorizontalScrollView,因為HorizontalScrollView提供了水平側滑的效果,然後測量菜單和內容界面的各個屬性,