设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)
- 定义
- 用的原因
- 缺点
- 角色
- 场景举例
定义
用编译语言的方式来分析应用中的实例
为什么要用
扩展性好,利用继承机制扩展文法
缺点
效率低,调用麻烦,容易引起类膨胀,这个模式很少能用到
角色
抽象表达式(Abstract Expression):定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
终结符表达式(Terminal Expression):是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
非终结符表达式(Nonterminal Expression):也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
上下文(Context):通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
场景举例
设计一个读卡器,北京或太原的老年和孕妇刷卡免费,其余人群标准价
首先设计文法
1 2 3
| <expression> ::= <city>的<person> <city> ::= 北京|太原 <person> ::= 老人|孕妇
|
uml类图

程序调用
1 2 3 4 5 6 7 8
| Context bus = new Context();
System.out.println("公交乘车开始刷卡"); bus.freeRide("北京的老人"); bus.freeRide("太原的孕妇"); bus.freeRide("太原的儿童"); bus.freeRide("上海的老人");
|
输出
1 2 3 4 5
| 公交乘车开始刷卡 哔!老人卡,欢迎乘车,您本次乘车免费! 哔!孕妇卡,欢迎乘车,您本次乘车免费! 哔!欢迎乘车,您本次乘车扣费2元! 哔!欢迎乘车,您本次乘车扣费2元!
|
抽象表达式
1 2 3
| public interface Expression { boolean interpret(String info); }
|
终结符表达式(具体实现者)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class TerminalExpression implements Expression{ private Set<String> set = new HashSet<String>(); public TerminalExpression(String[] data) { for (int i = 0; i < data.length; i++) { set.add(data[i]); } } public boolean interpret(String info) { if (set.contains(info)) { return true; } return false; } }
|
非终结符表达式(具体实现者)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class AndExpression implements Expression{ private Expression left; private Expression right; public static final String FLEX = "的"; public AndExpression(Expression city, Expression person) { this.left = city; this.right = person; } public boolean interpret(String info) { String s[] = info.split(FLEX); return left.interpret(s[0]) && right.interpret(s[1]); } }
|
上下文Context
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Context { private String[] citys = {"北京", "太原"}; private String[] persons = {"老人", "孕妇"}; private Expression expression; public Context() { Expression city = new TerminalExpression(citys); Expression person = new TerminalExpression(persons); expression = new AndExpression(city, person); } public void freeRide(String info) { String s1 = "哔!"+info.split(FLEX)[1] + "卡,欢迎乘车,您本次乘车免费!"; String s2 = "哔!欢迎乘车,您本次乘车扣费2元!"; System.out.println(expression.interpret(info) ? s1 : s2); } }
|