@@@模式定义:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,
这个解释器使用该表示来解释语言中的句子。
@@@练习示例:
输入一个模型公式,然后输入模型中的参数,运算出结果。
@@@示例代码:
/pattern/Expression.java
/pattern/VarExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/pattern/SymbolExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/pattern/AddExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/pattern/SubExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/pattern/Calculator.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/user/Client.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@@模式的实现:
继承抽象解释器的有终结表达式和非终结表达式。
@@@模式的优点:
1) 易于实现语法;
2) 易于扩展新的语法;
@@@模式的缺点:
不适合复杂的语法;
@@@模式的本质:
分离实现,解释执行
@@@模式体现的设计原则:
迪米特原则
给定一个语言,定义它的文法的一种表示,并定义一个解释器,
这个解释器使用该表示来解释语言中的句子。
@@@练习示例:
输入一个模型公式,然后输入模型中的参数,运算出结果。
@@@示例代码:
/pattern/Expression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
import java.util.HashMap;
public abstract class Expression {
// 解析公式和数值, 其中var中的key值是是公式中的参数, value值是具体的数字
public abstract int interpreter(HashMap<String, Integer> var);
}
/pattern/VarExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
import java.util.HashMap;
public class VarExpression extends Expression {
private String key;
public VarExpression(String _key){
this.key = _key;
}
@Override
public int interpreter(HashMap<String, Integer> var) {
// 从map中取值
return var.get(this.key);
}
}
/pattern/SymbolExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
public abstract class SymbolExpression extends Expression {
protected Expression left;
protected Expression right;
// 所有的解析公式都应只关心自己左右两个表达式的结果
public SymbolExpression(Expression _left, Expression _right){
this.left = _left;
this.right = _right;
}
}
/pattern/AddExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
import java.util.HashMap;
public class AddExpression extends SymbolExpression {
public AddExpression(Expression _left, Expression _right){
super(_left, _right);
}
// 把左右两个表达式运算的结果加起来
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
/pattern/SubExpression.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
import java.util.HashMap;
public class SubExpression extends SymbolExpression {
public SubExpression(Expression _left, Expression _right){
super(_left, _right);
}
// 把左右两个表达式运算的结果相减
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
/pattern/Calculator.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern;
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 SubExpression(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.interpreter(var);
}
}
/user/Client.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package user;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import pattern.Calculator;
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))){ // 解决重复参数的问题
System.out.print("请输入" + ch + "的值:");
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
}
@@@模式的实现:
继承抽象解释器的有终结表达式和非终结表达式。
@@@模式的优点:
1) 易于实现语法;
2) 易于扩展新的语法;
@@@模式的缺点:
不适合复杂的语法;
@@@模式的本质:
分离实现,解释执行
@@@模式体现的设计原则:
迪米特原则