java設計模式(行爲型)之解釋器模式

第0章:簡介

解釋器模式的定義:定義語言的文法,並且建立一個解釋器來解釋該語言中的句子。客戶端可以使用這個解釋器來解釋這個語言中的句子。

解釋器模式的本質:解釋語言的語法或表達式的方式

參考:研磨設計模式(書籍),大話設計模式(書籍),圖解設計模式(書籍)

模式圖:

待補充

第1章:實踐

(1)抽象表達式類(AbstractExpression.java)

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 抽象表達式類
 * (也可以用接口類)
 *
 * 本例文法:
 * 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 - -
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public abstract class AbstractExpression {

    /**
     * 解釋方法
     * @param context 上下文環境對象
     */
    public abstract int interpret(Context context);
}
(2)數字(number)終結符表達式類NumberTerminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 數字(number)終結符表達式類
 *
 * 文法中的每一個終結符都有一個具體終結表達式與之相對應
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class NumberTerminalExpression extends AbstractExpression {

    private int number;

    public NumberTerminalExpression(int number){
        this.number = number;
    }

    /**
     * 實現文法中與終結符number有關的解釋操作
     * @param context 上下文環境對象
     */
    @Override
    public int interpret(Context context) {
        return number;
    }
}

(3)變量(Variable)終結符表達式類VariableTerminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 變量(Variable)終結符表達式類
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class VariableTerminalExpression extends AbstractExpression {

    //變量名稱
    private String name;

    public VariableTerminalExpression(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    /**
     * 實現文法中與終結符變量有關的解釋操作
     * @param context 上下文環境對象
     * @return
     */
    @Override
    public int interpret(Context context) {

        return context.getValue(this);
    }
}

(4)加操作(Plus)非終結符表達式PlusNonterminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 加操作(Plus)非終結符表達式
 *
 * 文法中的每一條規則都需要一個具體的非終結符表達式,
 * 非終結符表達式一般是文法中的運算符或者其他關鍵字。
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class PlusNonterminalExpression extends AbstractExpression {

    //加操作左邊表達式
    private AbstractExpression leftExpression;
    //加操作右邊表達式
    private AbstractExpression rightExpression;

    public PlusNonterminalExpression(AbstractExpression leftExpression, AbstractExpression rightExpression){
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    /**
     *實現文法中與非終結符加有關的解釋操作
     * @param context 上下文環境對象
     * @return
     */
    @Override
    public int interpret(Context context) {
        return leftExpression.interpret(context) + rightExpression.interpret(context);
    }
}

(5)減操作(Minus)非終結符表達式MinusNonterminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 減操作(Minus)非終結符表達式
 *
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/30.
 */
public class MinusNonterminalExpression extends AbstractExpression {

    //減操作左邊表達式
    private AbstractExpression leftExpression;
    //減操作右邊表達式
    private AbstractExpression rightExpression;

    public MinusNonterminalExpression(AbstractExpression leftExpression, AbstractExpression rightExpression){
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    /**
     * 實現文法中與非終結符減有關的解釋操作
     * @param context 上下文環境對象
     * @return
     */
    @Override
    public int interpret(Context context) {
        return leftExpression.interpret(context) - rightExpression.interpret(context);
    }
}
(6)上下文環境類(Context.java

package com.mcc.core.designPattern.behavior.interpreter;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * 上下文環境類
 * 爲解釋器進行語法解釋提供了必要信息
 *
 * 解釋器的定義:定義語言的文法,並且建立一個解釋器來解釋該語言中的句子。客戶端可以使用這個解釋器來解釋這個語言中的句子。
 * 解釋器的本質:解釋語言的語法或表達式的方式
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class Context {

    //用於存放變量實例和對應值
    private Map<VariableTerminalExpression, Integer> valueMap = new HashMap<VariableTerminalExpression, Integer>();
    //用於存放變量名和對應實例
    private Map<String, VariableTerminalExpression> vriableTerminalExpressionMap = new HashMap<String, VariableTerminalExpression>();

    /**
     * 增加變量實例和對應值
     * @param variable
     * @param value
     */
    public void addValue(VariableTerminalExpression variable, Integer value){
        valueMap.put(variable,value);
        vriableTerminalExpressionMap.put(variable.getName(), variable);
    }

    /**
     * 獲取變量實例的值
     * @param variable
     * @return
     */
    public int getValue(VariableTerminalExpression variable){
        if(valueMap != null){
            return (Integer)valueMap.get(variable).intValue();
        }else{
            System.out.println("此處處理異常");
            return 0;
        }

    }

    /**
     * 解釋語法樹
     * @param expression
     * @return
     */
    public int parse(String expression){
        Stack<AbstractExpression> expressionStack = new Stack<AbstractExpression>();
        for (String token : expression.split(" ")) {
            //加操作處理
            if  (token.equals("+")) {
                AbstractExpression subExpression = new PlusNonterminalExpression(expressionStack.pop(), expressionStack.pop());
                expressionStack.push( subExpression );
            }
            //減操作處理
            else if (token.equals("-")) {
                // it's necessary remove first the right operand from the stack
                AbstractExpression rightExpression = expressionStack.pop();
                // ..and after the left one
                AbstractExpression leftExpression = expressionStack.pop();
                AbstractExpression subExpression = new MinusNonterminalExpression(leftExpression, rightExpression);
                expressionStack.push( subExpression );
            }
            else
                expressionStack.push( vriableTerminalExpressionMap.get(token) );
        }
        AbstractExpression abstractExpression = expressionStack.pop();

        return abstractExpression.interpret(this);
    }
}

(7)客戶端測試(Client.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 客戶端測試
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/30.
 */
public class Client {
    public static void main(String args[]){
        String expression = "w x z - +";
        Context context = new Context();
        context.addValue(new VariableTerminalExpression("w"),5);
        context.addValue(new VariableTerminalExpression("x"),10);
        context.addValue(new VariableTerminalExpression("z"),42);
        //解釋器解釋並返回結果
        int result = context.parse(expression);

        System.out.println(result);
    }
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章