什么是解释器模式
解释器模式就是针对一个有规则的场景,设计一个解释器,根据定好的规则解释具体场景并得到结果的设计模式。
设计一段代码,能够计算任意的加减乘除混合运算,那么这就是一个解释器。
侧重业务系统架构与开发的码农,使用解释器模式的场景比较少,工作中几乎不会遇到,该模式可以不做了解,直接跳过不用再看了。
解释器模式不同于以往的各种模式,不同之处不在于代码层面,而在思想层面。
以前说的二十二种设计模式,侧重点都是围绕着很有代表性的业务场景,设计出高内聚低耦合易扩展的解决方案,并用代码巧妙的实现。
解释器模式的侧重点稍有不同,它是围绕着业务场景,设计通用的业务规则,业务场景的具体解决方案反而不太关注。
举个例子来理解,金融领域涉及货币的流通,必然会有各种关于货币的计算模型,比如利息、罚息、贷款、等等的计算。
解释器模式不关注种类繁多的货币计算模型,它更关注计算规则!什么是规则?就是加减乘除等各种数学运算规则。设计这些规则并实现,就是解释器模式的用武之地。
当然,在现实业务场景中,数学运算规则早已有很多实现好的功能完善的类库可供使用,无需我们再造轮子。我想表达的意思就是,解释器模式适用于规则的制定、解释,还有实现,关注的是业务场景更底层的东西。
设计与实现
规则设计
解释器模式定义的是规则与实现,那么对于规则本身来讲,就应该有两个要点。
规则的语法
语法就是规则的表达方式。
比如,加法规则的表达方式就是a + b
,其中a、b
是数字变量,+
是加法符号。
再比如,乘法规则的表达方式是a * b
,其中a、b
是数字变量,*
是乘法符号。
加法和乘法同时存在的时候,还要定义个运算优先级,否则会出现运算歧义。都知道的,乘法优先级高于加法。
语法的解析
语法是规则的最小单元,多个语法混合搭配使用就能形成复杂的业务场景,比如定义a + b * c
这么一个场景,其中就包含加法和乘法两个语法规则。
语法解析就是针对给定的场景,将其按规则拆解运算,得到最终的计算结果。
对于a + b * c
来说,就需要先计算*
再计算+
得出结果。
代码实现
实现这么一个业务场景:计算正整数范围的加法和乘法运算,语法输入规则只能包含正整数和加法乘法符号,不能含有空格等其它字符。
代码实现大致可以这样:
// 解释器:解析正整数范围内,只含加法和乘法的运算
public class Interpreter {
/**
* example:
* expression = "1+2+3+4"
* expression = "1*2*3*4"
* expression = "1+2*3*4"
*
* @param expression
* @return
*/
public int interpret(String expression) {
List<String> nums = new ArrayList<>(), symbols = new ArrayList<>();
nums.addAll((Arrays.asList(expression.split("[+|*]"))));
symbols.addAll(Arrays.asList(expression.split("\\d+")));
symbols.remove(0);
for (int i = 0; i < symbols.size(); i++) {
String symbol = symbols.get(i);
if ("*".equals(symbol)) {
int num1 = Integer.valueOf(nums.get(i));
int num2 = Integer.valueOf(nums.get(i + 1));
nums.set(i, null);
nums.set(i + 1, String.valueOf(num1 * num2));
}
}
int sum = 0;
for (String num : nums) sum += num == null ? 0 : Integer.valueOf(num);
return sum;
}
}
// 测试方法
public static void main(String[] args) {
String expression = "1*2*3+4";
Interpreter interpreter = new Interpreter();
int sum = interpreter.interpret(expression);
System.out.println(sum);
}
这个解释器非常非常的简单,只能做个示例。
实际当中,如果规则非常多且复杂,那么设计解释器的时候,通常还会穿插应用其它的设计模式,使其内部的设计更为合理。