Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> java/android 設計模式學習筆記(23)---解釋器模式

java/android 設計模式學習筆記(23)---解釋器模式

編輯:關於Android編程

這篇博客我們來介紹一下解釋器模式(Interpreter Pattern),也是行為型設計模式之一,是一種用的比較少的設計模式,其提供了一種解釋語言的語法或表達式的方式,該模式定義了一個表達式接口,通過該接口解釋一個特定的上下文。在這麼多的設計模式中,解釋器模式在實際運用上相對來說要少很多,因為我們很少會去構造一個語言的文法。雖然你幾乎用不到這個模式,但是看一看還是能受到一定的啟發的。

特點

給定一個語言,定義它的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中的句子。
  該模式的使用場景相當廣泛,總的概括下來大概有以下幾種:

專用的數據庫查詢語言,比如 SQL;通常用來解釋通信協議的專用計算機語言;如果某個簡單的語言需要解釋執行而且可以將語言中的語句表示為一個抽象語法樹時可以考慮使用解釋器模式。

 

UML類圖

我們來看看解釋器模式的 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(Map variables);
}

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) {
        Stack expressionStack = 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);
        Map variables = 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

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved