源代码
GitHub源代码
1.本文目标
本文目标是为了让大家认识并理解解释器模式
2.基本套路
定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
类型:行为型
选择关键点:被频繁使用的语言是否可用文法表示
设计原则:遵循单一职责
使用概率:0.00009%
难度系数:中
3.适用场景
1.某个特定类型问题发生频率足够高
4.使用步骤
用栗子能更好的说明问题,请继续往下看
5.举个栗子
我们用具体的代码去更好的理解这个设计模式
5.1栗子说明
- 背景:输入一个字符串,通过自定义解释器,去得到一个结果
- 目的:用解释器模式自定义
5.2使用步骤
实现代码如下:
步骤1.创建解释器接口
public interface Interpreter {
int interpret();
}
步骤2.创建加法解释器 实现解释器接口
public class AddInterpreter implements Interpreter {
private Interpreter firstExpression, secondExpression;
public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
this.firstExpression = firstExpression;
this.secondExpression = secondExpression;
}
@Override
public int interpret() {
return this.firstExpression.interpret() + this.secondExpression.interpret();
}
@Override
public String toString() {
return "+";
}
}
步骤3.创建乘法解释器 实现解释器接口
public class MultiInterpreter implements Interpreter {
private Interpreter firstExpression,secondExpression;
public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression){
this.firstExpression=firstExpression;
this.secondExpression=secondExpression;
}
@Override
public int interpret(){
return this.firstExpression.interpret()*this.secondExpression.interpret();
}
@Override
public String toString(){
return "*";
}
}
步骤4. 创建数字解释器 实现解释器接口
public class NumberInterpreter implements Interpreter {
private int number;
public NumberInterpreter(int number) {
this.number = number;
}
public NumberInterpreter(String number) {
this.number = Integer.parseInt(number);
}
@Override
public int interpret() {
return this.number;
}
}
步骤5. 创建工具类
public class OperatorUtil {
public static boolean isOperator(String symbol) {
return (symbol.equals("+") || symbol.equals("*"));
}
public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
if (symbol.equals("+")) {
return new AddInterpreter(firstExpression, secondExpression);
} else if (symbol.equals("*")) {
return new MultiInterpreter(firstExpression, secondExpression);
}
return null;
}
}
步骤6. 创建自定义解释器,去解释字符串
public class MyExpressionParser {
private Stack<Interpreter> stack = new Stack<Interpreter>();
public int parse(String str) {
String[] strItemArray = str.split(" ");
for (String symbol : strItemArray) {
if (!OperatorUtil.isOperator(symbol)) {
Interpreter numberExpression = new NumberInterpreter(symbol);
stack.push(numberExpression);
System.out.println(String.format("入栈: %d", numberExpression.interpret()));
} else {
//是运算符号,可以计算
Interpreter firstExpression = stack.pop();
Interpreter secondExpression = stack.pop();
System.out.println(String.format("出栈: %d 和 %d",
firstExpression.interpret(), secondExpression.interpret()));
Interpreter operator = OperatorUtil.getExpressionObject(firstExpression, secondExpression, symbol);
System.out.println(String.format("应用运算符: %s", operator));
int result = operator.interpret();
NumberInterpreter resultExpression = new NumberInterpreter(result);
stack.push(resultExpression);
System.out.println(String.format("阶段结果入栈: %d", resultExpression.interpret()));
}
}
int result = stack.pop().interpret();
return result;
}
}
步骤7. 测试
public static void main(String[] args) {
//输入字符串,自己定义的一套算法
String geelyInputStr="6 100 11 + *";
MyExpressionParser expressionParser=new MyExpressionParser();
int result=expressionParser.parse(geelyInputStr);
/**
* 结果:
* 100+11=111 111*6=666
*/
System.out.println("解释器计算结果: "+result);
}
6.优点
- 语法由很多类表示,容易改变和扩展此"语言"
7.缺点
- 当语法规则数目太多时,增加了系统复杂度
8.总结
本文只是对解释器模式进行一个分享,接下来会从创建型模式,结构型模式,行为型模式,这三大类展开一个系列分享,大家可以持续进行关注,信仰年輕的设计模式,蟹蟹啦。
网友评论