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