天天看點

【設計模式二十六之解釋器模式】解釋器模式細說模闆名稱

解釋器模式

  • 細說模闆名稱
    • 細說解釋器模式
      • 定義
      • UML模型
        • 基于UML的代碼
      • 場景一
        • 場景
        • 代碼
      • 解釋器模式應用和注意事項

細說模闆名稱

提示:

部落客:章飛 _906285288的部落格

部落格位址:http://blog.csdn.net/qq_29924041

細說解釋器模式

解釋器模式,說句實話 ,我真的不是特别想寫這個解釋器模式,因為這玩意了解起來雖然不難,但是在實際應用中還是比較難的,算是在設計模式中比較難的一類設計模式。應用場景從目前開發來看,應用并不是那麼的廣泛,是以簡單扯扯。

定義

解釋器模式:就是按照一定的文法和規則進行解析的方案。給定一門語言,定義它的文法,并定義一個解釋器對原來的文法進行解釋

其實解釋器就是翻譯機而已,但是文法和邏輯複雜啊

UML模型

【設計模式二十六之解釋器模式】解釋器模式細說模闆名稱

從圖上看其實解釋器模式好像也沒什麼元素内容:

1:AbstractExpression抽象的解釋器,具體的解釋任務由各個子類進行實作

2:TerminalExpression終結符解釋器,每個解釋器都要有終結符号的啊,不然怎麼知道翻譯結束了呢

3:NonterminalExpression 非終結符解釋器,每個文法規則對應的非終結文法

4:Context 環境角色

基于UML的代碼

package src.com.zzf.designpattern.interpreterpattern.demo2;


/**
 * 抽象解釋器,具體的解釋任務由各個實作類來完成,
 * @author Administrator
 *
 */
public abstract class AbstractExpression {
	public abstract Object interpreter(Context ctx);
}

           
package src.com.zzf.designpattern.interpreterpattern.demo2;

import src.com.zzf.designpattern.interpreterpattern.demo1.Expression;

/**
 * 非終結符表達式
 * @author Administrator
 *
 */
public class NonterminalExpression extends AbstractExpression{
	
	
	public NonterminalExpression(Expression ...expressions){
		
	}
	
	@Override
	public Object interpreter(Context ctx) {
		// TODO Auto-generated method stub
		return null;
	}

}

           
package src.com.zzf.designpattern.interpreterpattern.demo2;


/**
 * 終結符表達式,通常隻有一個,但是可以對應多個對象
 * @author Administrator
 *
 */
public class TerminalExpression extends AbstractExpression {
	
	@Override
	public Object interpreter(Context ctx) {
		// TODO Auto-generated method stub
		return null;
	}

}

           
package src.com.zzf.designpattern.interpreterpattern.demo2;

import java.util.Stack;

import src.com.zzf.designpattern.interpreterpattern.demo1.Expression;

public class Context {
	public static void main(String[] args) {
		Context ctx = new Context(); 
		Stack<Expression> stack = null;
		for(;;){
			//進行文法填充
		 }
		Expression exp = stack.pop();
		exp.interpreter(ctx);
	}
}

           

可以看到起其uml的代碼其實沒有任何run的意義,其實解釋器模式确實是一種思想,就是如果結合文法翻譯規則翻譯出正确的結果。

最最重要的是分析文法規則的共性與特性,然後才能解釋

場景一

場景

照搬設計模式之禅中的四則運算

代碼

package src.com.zzf.designpattern.interpreterpattern.demo1;


import java.util.HashMap;

/**
 * 抽象的解釋器
 * @author zhouzhangfei
 *
 */
public abstract class Expression {
	public abstract int interperter(HashMap<String, Integer> var);
}

           
package src.com.zzf.designpattern.interpreterpattern.demo1;


import java.util.HashMap;

/**
 * 變量解釋器
 * @author Administrator
 *
 */
public class VarExpression extends Expression {
	private String key;
	
	public VarExpression(String key){
		this.key = key;
	}
	
	@Override
	public int interperter(HashMap<String, Integer> var) {
		// TODO Auto-generated method stub
		return var.get(key);
	}

}

           
package src.com.zzf.designpattern.interpreterpattern.demo1;


/**
 * 抽象的符号解釋器
 * @author zhouzhangfei
 *
 */
public abstract class SymbolExpression extends Expression{
	protected Expression left;
	protected Expression right;
	//所有的解析公式都隻關心自己左右兩個表達式的結果
	public SymbolExpression(Expression _left,Expression _right){
		this.left = _left;
		this.right = _right;
	}

}

           
package src.com.zzf.designpattern.interpreterpattern.demo1;

import java.util.HashMap;

/**
 * 加法解釋器
 * @author zhouzhangfei
 *
 */
public class AddExpression extends SymbolExpression{
	public AddExpression(Expression _left,Expression _right){
		super(_left,_right);
		}
	
	@Override
	public int interperter(HashMap<String, Integer> var) {
		// TODO Auto-generated method stub
		return super.left.interperter(var) + super.right.interperter(var);
	}

}

           
package src.com.zzf.designpattern.interpreterpattern.demo1;

import java.util.HashMap;
/**
 * 減法解釋器
 * @author zhouzhangfei
 *
 */
public class DeleteExpression extends SymbolExpression{

	public DeleteExpression(Expression _left, Expression _right) {
		super(_left, _right);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int interperter(HashMap<String, Integer> var) {
		// TODO Auto-generated method stub
		return super.left.interperter(var) - super.right.interperter(var);
	}

}

           

運算器

package src.com.zzf.designpattern.interpreterpattern.demo1;

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

public class Calculator {
	private Expression expression;
	public Calculator(String expStr){
		Stack<Expression> stack = new Stack<Expression>();
		char[] charArray = expStr.toCharArray();
		Expression left = null;
		Expression right = null;
		for(int i=0;i<charArray.length;i++){
			switch(charArray[i]) {
			case '+':
				left = stack.pop();
				right=new VarExpression(String.valueOf(charArray[++i]));
				stack.push(new AddExpression(left,right));
				break;
			case '-':
				left = stack.pop();
				right=new VarExpression(String.valueOf(charArray[++i])) ;
				stack.push(new DeleteExpression(left,right));
				break;
			default: //
				stack.push(new VarExpression(String.valueOf(charArray[i])));
			}
		}
		this.expression = stack.pop();
	}
	public int run(HashMap<String,Integer> var){
		return this.expression.interperter(var);
	}
}

           
package src.com.zzf.designpattern.interpreterpattern.demo1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

public class Client {
	public static void main(String[] args) throws IOException {
		String expStr = getExpStr();
		HashMap<String, Integer> var = getValue(expStr);
		Calculator cal = new Calculator(expStr);
		System.out.println("" + expStr + "=" + cal.run(var));
	}

	public static String getExpStr() throws IOException {
		System.out.print("請輸入");
		return new BufferedReader(new InputStreamReader(System.in)).readLine();
	}

	// 
	public static HashMap<String,Integer> getValue(String exprStr) throws IOException{
		HashMap<String,Integer> map = new HashMap<String,Integer>();
		for(char ch:exprStr.toCharArray()){
			if(ch != '+' && ch != '-'){
				if(!map.containsKey(String.valueOf(ch))){
					String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
					map.put(String.valueOf(ch),Integer.valueOf(in));
				}
			}
		}
		return map;
	}
}
           

解釋器模式應用和注意事項

解釋器模式其實是一個簡單文法的分析工具,具有良好的擴充性,但是如果要去解析一系列複雜文法的時候,這個時候解釋器模式可能會出現類似類膨脹,再由于解釋器模式其實使用的遞歸等,是以很容易引發一些效率上的問題。是以其在實際的開發過程中是比較少用的,但是還是很有必要進行了解,畢竟在某些業務場景下還是有可能會使用到的。再加上其思想的先進性。

歡迎繼續通路,我的部落格

繼續閱讀