【Java设计模式】· 解释器模式(Interpreter Pattern)

解释器模式:


 



              1. 当我们解决问题时,需要重复多次使用某个方法,为了方便,我们就会专门为这个方法写一个类,这就是解释器模式。


              2.解释器模式  和  享元模式的不同在哪儿?   两个模式共同点是解决"重复多次调用"的问题,享元模式是解决元素多次使用的问题,它的作用是解决这类问题的同时还节省了内存空间。 解释器模式是解决方法多次使用的问题,它作用是让我们在解决问题时不需要写太多的代码。


              3.解释器模式最好的例子是四则运算:


定义四则运算的父类:

package pers.reus.model.abstractExpression;

import pers.reus.model.context.Context;

//四则运算的抽象类,定义一个计算方法
public abstract class AbstractExpression {
	 public abstract int interpreter(Context context);
}

加法运算

package pers.reus.model.concreteExpression;

import pers.reus.model.abstractExpression.AbstractExpression;
import pers.reus.model.context.Context;

public class AddExpression extends AbstractExpression{
	//定义左子树和右子树
	private AbstractExpression left;
    private AbstractExpression right;

    public AddExpression(AbstractExpression left, AbstractExpression right)
    {
        this.left = left;
        this.right = right;
    }

    public int interpreter(Context context)
    {
    	//返回两数的和	
        return this.left.interpreter(context) + this.right.interpreter(context);
    }

}

减法运算

package pers.reus.model.concreteExpression;

import pers.reus.model.abstractExpression.AbstractExpression;
import pers.reus.model.context.Context;

public class SubtractExpression extends AbstractExpression{

	private AbstractExpression left;
	private AbstractExpression right;
	
	public SubtractExpression(AbstractExpression left,AbstractExpression right){
		this.left = left;
		this.right = right;
	}
	
	public int interpreter(Context context) {
		//返回两数的差
		return this.left.interpreter(context) - this.right.interpreter(context);
	}

}

乘法运算

package pers.reus.model.concreteExpression;

import pers.reus.model.abstractExpression.AbstractExpression;
import pers.reus.model.context.Context;

public class MultiplyExpression extends AbstractExpression{
	
	private AbstractExpression left;
	private AbstractExpression right;
	
	public MultiplyExpression(AbstractExpression left, AbstractExpression right){
		this.left = left;
        this.right = right;
	}
	
	public int interpreter(Context context) {
		//返回两数的积	
		return this.left.interpreter(context)*this.right.interpreter(context);
	}

}


除法运算

package pers.reus.model.concreteExpression;

import pers.reus.model.abstractExpression.AbstractExpression;
import pers.reus.model.context.Context;

public class DivisionExpression extends AbstractExpression{
		
	 	private AbstractExpression left;
	    private AbstractExpression right;

	    public DivisionExpression(AbstractExpression left,AbstractExpression right)
	    {
	        this.left = left;
	        this.right = right;
	    }

	    public int interpreter(Context context)
	    {
	    	//除法分母不能为0,先用value=分母
	        int value = this.right.interpreter(context);
	        //当分母不为0时
	        if (value != 0)
	        {
	        	//返回两数的商
	            return this.left.interpreter(context) / value;
	        }
	        //否则返回-999999
	        return -999999;
	    }

<span style="font-size:18px;"><span style="font-size:12px;">}</span>
</span>


终结表达符,上面的四则运算在构造函数时的形参要求是AbstactExpression,也就是说,如果直接把Context传入AddExpression是不可以的,所有先用终结表达符转换。

package pers.reus.model.concreteExpression;

import pers.reus.model.abstractExpression.AbstractExpression;
import pers.reus.model.context.Context;

//终结表达符
public class TerminalExpression extends AbstractExpression{
	 private int i;
	 	//这里的i会是context.getValue("X");
	    public TerminalExpression(int i)
	    {
	        this.i = i;
	    }

	    public int interpreter(Context context)
	    {
	        return this.i;
	    }
}

Context类是存储数的类

package pers.reus.model.context;

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

public class Context {
	 //Map存一个数,String是数的名称,Integer是数值
	 private final Map<String, Integer> valueMap = new HashMap<String, Integer>();
	 
	 //把数存入Map
	 public void addVaule(String str,Integer value){
		 valueMap.put(str, Integer.valueOf(value));
	 }
	 
	 //从Map里通过数的名称提取数值
	 public int getValue(String str){
		 return valueMap.get(str).intValue();
	 }
}

测试:

package pers.reus.model.client;

import pers.reus.model.concreteExpression.AddExpression;
import pers.reus.model.concreteExpression.DivisionExpression;
import pers.reus.model.concreteExpression.MultiplyExpression;
import pers.reus.model.concreteExpression.SubtractExpression;
import pers.reus.model.concreteExpression.TerminalExpression;
import pers.reus.model.context.Context;

public class InterpreterPatternClient {

	public static void main(String[] args) {
		// 声明Context用来存数
		Context context = new Context();

		// a=1,b=2,c=3存入Map
		context.addVaule("a", 1);
		context.addVaule("b", 2);
		context.addVaule("c", 3);
		
		//将Map的数放入终结符
		TerminalExpression a = new TerminalExpression(context.getValue("a"));
		TerminalExpression b = new TerminalExpression(context.getValue("b"));
		TerminalExpression c = new TerminalExpression(context.getValue("c"));

		//计算
		MultiplyExpression multiplyValue = new MultiplyExpression(a, b);

		SubtractExpression subtractValue = new SubtractExpression(a, b);

		AddExpression addValue = new AddExpression(subtractValue, c);

		DivisionExpression divisionValue = new DivisionExpression(
				multiplyValue, addValue);

		System.out.println("(a*b)/(a-b+c) = " + divisionValue.interpreter(context));

	}

}

结果:
(a*b)/(a-b+c) = 1


总结:其实解释器模式是最常见的一种模式,把方法总结归类就是编程进步的一大思想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值