设计方式之行为模式——解释器(Interpreter)模式

设计模式之行为模式——解释器(Interpreter)模式

     继续我们的《设计模式》的学习课程!今天我要讲的是解释器——Interpreter模式,因为昨天同事刚讲了这个模式,趁着脑子里面还有印象,赶紧通过写这篇文章来巩固下!

 

         定义:定义语言的文法,并且建立一个解释器来解释该语言中的句子。它属于类的行为模式。这里的语言意思是使用规定格式和语法的代码。

        意图:抽取语法中最基本的功能,以便于进行代码重用

        类图:


设计方式之行为模式——解释器(Interpreter)模式

 

   涉及的角色有:

   1、Expression :表达式,是一个接口或抽象类;

   2、TerminalExpression :终结符表达式角色,是表达式的一个子类或实现类

   3、NonterminalOneExpression : 非终结符表达式角色,也是表达式的一个子类或实现类

   4、Context :上下文环境

 

示例如下:

 

package service;

import impl.Context;

import java.math.BigDecimal;

/*
 * 抽象表达式
 */
public interface Expression 
{
   public BigDecimal interpreter(Context con);
}

 

 

 

package impl;

import java.math.BigDecimal;
import java.util.Hashtable;

import service.Expression;

/*
 * 语法上下文
 */
public class Context 
{
	private Hashtable table;
	
	public Context()
	{
		this.table = new Hashtable<Expression,BigDecimal>();
	}
	
	public void addValue(Expression pression,BigDecimal value)
	{
		this.table.put(pression, value);
	}
	
	public BigDecimal getValue(Expression pression)
	{
		BigDecimal value = (BigDecimal) this.table.get(pression);
		return value;
	}
   
}
 

 

 

 

package impl;

import java.math.BigDecimal;

import service.Expression;
/*
 * 变量(终结符表达式)
 */
public class Varial implements Expression 
{

	public BigDecimal interpreter(Context con) 
	{		
		BigDecimal value = con.getValue(this);
		return value;
	}

}

 

 

 

package impl;

import java.math.BigDecimal;

import service.Expression;
/*
 * 常量
 */
public class Constant implements Expression {

	private BigDecimal data;
	public Constant(BigDecimal value)
	{
		this.data = value;
	}
	
	@Override
	public BigDecimal interpreter(Context con) 
	{		
		return data;
	}

}

 

 

 

 

package impl;

import java.math.BigDecimal;

import service.Expression;

public class AddExpression implements Expression {

	private Expression left;
	
	private Expression right;
	
	@Override
	public BigDecimal interpreter(Context con) 
	{
		
		return left.interpreter(con).add(right.interpreter(con));
	}
	
	public AddExpression(Expression left,Expression right)
	{
		this.left = left;
		this.right = right;
	}

}

 

 

 

package impl;

import java.math.BigDecimal;

import service.Expression;

public class DivExpression implements Expression {

	private Expression left;
	
	private Expression right;
	@Override
	public BigDecimal interpreter(Context con) 
	{
		//两个BigDecimal对象相除时,如果除不尽,则会报错,所以要进行舍入
		return left.interpreter(con).divide(right.interpreter(con),2,BigDecimal.ROUND_HALF_UP);
	}
	
	public DivExpression(Expression left,Expression right)
	{
		this.left = left;
		this.right = right;
	}

}
 

 

 

package impl;

import java.math.BigDecimal;

import service.Expression;

public class MultipExpression implements Expression {

	private Expression left;
	
	private Expression right;
	
	@Override
	public BigDecimal interpreter(Context con) 
	{
		return left.interpreter(con).multiply(right.interpreter(con));
	}
	
	public MultipExpression(Expression left,Expression right)
	{
		this.left = left;
		this.right = right;
	}

}

 

 

package client;

import impl.AddExpression;
import impl.Constant;
import impl.Context;
import impl.DivExpression;
import impl.MultipExpression;
import impl.SubtracExpression;
import impl.Varial;

import java.math.BigDecimal;

import service.Expression;

public class TestInterpreter {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		//(a*b*b)/(a+b-3)
		Context ctx = new Context();
		Expression a = new Varial();
		Expression b = new Varial();
		Expression c = new Constant(new BigDecimal("3"));
		ctx.addValue(a, new BigDecimal("6"));
		ctx.addValue(b, new BigDecimal("8"));
		ctx.addValue(c, c.interpreter(null));
        Expression rs = new DivExpression(new MultipExpression(a, new MultipExpression(b, b)), new SubtracExpression(new AddExpression(a, b), c));
        BigDecimal result = rs.interpreter(ctx);
        System.out.println("计算结果:"+result);
	}

}
 

 

 

package impl;

import java.math.BigDecimal;

import service.Expression;

public class SubtracExpression implements Expression
{
	private Expression left;
	
	private Expression right;

	@Override
	public BigDecimal interpreter(Context con) 
	{
		return left.interpreter(con).subtract(right.interpreter(con));
	}
	
	public SubtracExpression(Expression left,Expression right)
	{
		this.left = left;
		this.right = right;
	}
    
}

 

总结:

解释器以我个人的理解的话,首先它使用的场合不是很多,它适合于解释某种语言或规则。在解释这些规则时要

注意查找规律性的东西,把最基本的功能抽取出来,然后才能利用!