解释器模式 Interpreter 行为型 设计模式(十九)

public static int add(int a,int b){
return a+b;
}
public static int add(int a,int b,int c){
return a+b-c;
}
package function; @FunctionalInterface
public interface Function1<A,B,C,D,E,F,G, R> {
R xxxxx(A a,B b,C c,D d,E e,F f,G g);
}

意图
语法规则描述
| 范式基本规则 |
|
::= 表示定义,由什么推导出
尖括号 < > 内为必选项;
方括号 [ ] 内为可选项;
大括号 { } 内为可重复0至无数次的项;
圆括号 ( ) 内的所有项为一组,用来控制表达式的优先级
竖线 | 表示或,左右的其中一个
引号内为字符本身,引号外为语法(比如 'for'表示关键字for )
|
|
expression:=value | plus | minus
plus:=expression ‘+’ expression
minus:=expression ‘-’ expression
value:=integer
|
|
值的类型为整型数
有加法规则和减法规则
表达式可以是一个值,也可以是一个plus或者minus
而plus和minus又是由表达式结合运算符构成
可以看得出来,有递归嵌套的概念
|
抽象语法树

结构

终结符和非终结符
角色示例解析
|
expression:=value | plus | minus
plus:=expression ‘+’ expression
minus:=expression ‘-’ expression
value:=integer
|

package interpret;
public abstract class AbstractExpression {
public abstract int interpret();
}
package interpret;
public class Value extends AbstractExpression {
private int value;
Value(int value){
this.value = value;
}
@Override
public int interpret() {
return value;
}
}
package interpret;
public class Plus extends AbstractExpression {
private AbstractExpression left;
private AbstractExpression right;
Plus(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() + right.interpret();
}
}
package interpret;
public class Minus extends AbstractExpression {
private AbstractExpression left;
private AbstractExpression right;
Minus(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() - right.interpret();
}
}
package interpret;
public class Client {
public static void main(String[] args) {
AbstractExpression expression = new Minus(
new Plus(new Plus(new Plus(new Value(1), new Value(2)), new Value(3)), new Value(4)),
new Value(5));
System.out.println(expression.interpret());
}
}

int f(int x) {
if (1 == x) {
return x;
} else {
return x+f(x-1);
}
}
package interpret;
public class Variable extends AbstractExpression{
private String name;
private Integer value;
Variable(String name,Integer value){
this.name = name;
this.value = value;
}
public void setValue(Integer value) {
this.value = value;
}
@Override
public int interpret() {
return value;
}
}
package interpret;
public class Client {
public static void main(String[] args) {
//定义变量X和Y,初始值都为0
Variable variableX = new Variable("x", 0);
Variable variableY = new Variable("y", 0);
//计算公式为: X+Y+X-1
AbstractExpression expression2 = new Minus(new Plus(new Plus(variableX, variableY), variableX),
new Value(1));
variableX.setValue(1);
variableY.setValue(3);
System.out.println(expression2.interpret());
variableX.setValue(5);
variableY.setValue(6);
System.out.println(expression2.interpret());
}
}

代码示例

package interpret.refactor;
public abstract class AbstractExpression {
public abstract int interpret(Context ctx);
}
package interpret.refactor;
public class Value extends AbstractExpression {
private int value;
Value(int value) {
this.value = value;
}
@Override
public int interpret(Context ctx) {
return value;
}
@Override
public String toString() {
return new Integer(value).toString();
}
}
package interpret.refactor;
public class Variable extends AbstractExpression {
private String name;
Variable(String name) {
this.name = name;
}
@Override
public int interpret(Context ctx) {
return ctx.getValue(this);
}
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof Variable) {
return this.name.equals(
((Variable) obj).name);
}
return false;
}
@Override
public int hashCode() {
return this.toString().hashCode();
}
@Override
public String toString() {
return name;
}
}
package interpret.refactor;
public class Plus extends AbstractExpression {
private AbstractExpression left;
private AbstractExpression right;
Plus(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context ctx) {
return left.interpret(ctx) + right.interpret(ctx);
}
@Override
public String toString() {
return "(" + left.toString() + " + " + right.toString() + ")";
}
}
package interpret.refactor;
public class Minus extends AbstractExpression {
private AbstractExpression left;
private AbstractExpression right;
Minus(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context ctx) {
return left.interpret(ctx) - right.interpret(ctx);
}
@Override
public String toString() {
return "(" + left.toString() + " - " + right.toString() + ")";
}
}
package interpret.refactor;
import java.util.HashMap;
import java.util.Map;
public class Context {
private Map<Variable, Integer> map = new HashMap<Variable, Integer>();
public void assign(Variable var, Integer value) {
map.put(var, new Integer(value));
}
public int getValue(Variable var) {
Integer value = map.get(var);
return value;
}
}
package interpret.refactor;
public class Client {
public static void main(String[] args) {
Context ctx = new Context();
Variable a = new Variable("a");
Variable b = new Variable("b");
Variable c = new Variable("c");
Variable d = new Variable("d");
Variable e = new Variable("e");
Value v = new Value(1);
ctx.assign(a, 1);
ctx.assign(b, 2);
ctx.assign(c, 3);
ctx.assign(d, 4);
ctx.assign(e, 5);
AbstractExpression expression = new Minus(new Plus(new Plus(new Plus(a, b), c), d), e);
System.out.println(expression + "= " + expression.interpret(ctx));
}
}

/**
* 解析字符串,构造抽象语法树 方法只是为了理解:解释器模式 方法默认输入为合法的字符串,没有考虑算法优化、效率或者不合法字符串的异常情况
*
* @param sInput 合法的加减法字符串 比如 1+2+3
*/
public static AbstractExpression getAST(String sInput) {
//接收字符串参数形如 "1+2-3"
//将字符串解析到List valueAndSymbolList中存放
List<String> valueAndSymbolList = new ArrayList<>();
//先按照 加法符号 + 拆分为数组,以每个元素为单位使用 +连接起来存入List
//如果以+ 分割内部还有减法符号 - 内部以减法符号- 分割
//最终的元素的形式为 1,+,2,-,3
String[] splitByPlus = sInput.split("\\+");
for (int i = 0; i < splitByPlus.length; i++) {
if (splitByPlus[i].indexOf("-") < 0) {
valueAndSymbolList.add(splitByPlus[i]);
} else {
String[] splitByMinus = splitByPlus[i].split("\\-");
for (int j = 0; j < splitByMinus.length; j++) {
valueAndSymbolList.add(splitByMinus[j]);
if (j != splitByMinus.length - 1) {
valueAndSymbolList.add("-");
}
}
}
if (i != splitByPlus.length - 1) {
valueAndSymbolList.add("+");
}
}
//经过前面处理元素的形式为 1,+,2,-,3
//转换为抽象语法树的形式
AbstractExpression leftExpression = null;
AbstractExpression rightExpression = null;
int k = 0;
while (k < valueAndSymbolList.size()) {
if (!valueAndSymbolList.get(k).equals("+") && !valueAndSymbolList.get(k).equals("-")) {
rightExpression = new Value(Integer.parseInt(valueAndSymbolList.get(k)));
if (leftExpression == null) {
leftExpression = rightExpression;
}
}
k++;
if (k < valueAndSymbolList.size()) {
rightExpression = new Value(Integer.parseInt(valueAndSymbolList.get(k + 1)));
if (valueAndSymbolList.get(k).equals("+")) {
leftExpression = new Plus(leftExpression, rightExpression);
} else if (valueAndSymbolList.get(k).equals("-")) {
leftExpression = new Minus(leftExpression, rightExpression);
}
k++;
}
}
return leftExpression;
}

总结
解释器模式 Interpreter 行为型 设计模式(十九)的更多相关文章
- 设计模式15:Interpreter 解释器模式(行为型模式)
Interpreter 解释器模式(行为型模式) 动机(Motivation) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变 ...
- 设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
设计模式 ( 十九 ) 模板方法模式Template method(类行为型) 1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行 ...
- 二十四种设计模式:解释器模式(Interpreter Pattern)
解释器模式(Interpreter Pattern) 介绍给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 示例有一个Message实体类,某个类对它的 ...
- 迭代器模式 Iterator 行为型 设计模式(二十)
迭代器模式(Iterator) 走遍天下,世界那么大,我想去看看 在计算机中,Iterator意为迭代器,迭代有重复的含义,在程序中,更有“遍历”的含义 如果给定一个数组,我们可以通过for循 ...
- 乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern)
原文:乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern) 作 ...
- 命令模式 Command 行为型 设计模式(十八)
命令模式(Command) 请分析上图中这条命令的涉及到的角色以及执行过程,一种可能的理解方式是这样子的: 涉及角色为:大狗子和大狗子他妈 过程为:大狗子他妈角色 调用 大狗子的“回家吃饭”方法 引子 ...
- C#设计模式:解释器模式(Interpreter Pattern)
一,C#设计模式:解释器模式(Interpreter Pattern) 1,解释器模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易 ...
- 设计模式 笔记 解释器模式 Interpreter
//---------------------------15/04/26---------------------------- //Interpreter 解释器模式----类行为型模式 /* 1 ...
- 访问者模式 Visitor 行为型 设计模式(二十七)
访问者模式 Visitor <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白: “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...
随机推荐
- 我眼中的 Nginx(六):深入 Nginx/Openresty 服务里的 DNS 解析
张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护.Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的 ...
- 国内开源社区巨作AspectCore-Framework入门
前些天和张队(善友),lemon(浩洋),斌哥(项斌)等MVP大咖一块儿吃饭,大家聊到了lemon名下的AOP这个项目,我这小白听得一脸懵逼,后面回来做了一下功课,查了下资料,在lemon的Githu ...
- 使用工厂模式解耦和IoC思想
使用工厂模式解耦. 一.需求场景: 某一层功能需要改动,但其他层代码不变 实现类1:MyDaoImpl查询自己的数据库. ====改为====> 实现类2:MyDaoImpl2从其它地址得到数据 ...
- Jenkins忘记admin密码处理方法
1.先找到enkins/config.xml文件,并备份. 此文件位于Jenkins系统设置的主目录,根据自己的配置情况而定.我的位置如下 /data/temp/jenkins/config.xml2 ...
- 为什么HTTPS比HTTP更安全?
摘要: 理解HTTPS. 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 近几年,互联网发生着翻天覆地的变化,尤其是我们一直习以为常的HTTP协议,在逐渐的被HTTPS协议所取代 ...
- Fundebug支付宝小程序BUG监控插件更新至0.2.0,新增test()方法,报错增加Page数据
摘要: 0.2.0新增fundebug.test()方法,同时报错增加了Page数据. Fundebug提供专业支付宝小程序BUG监控服务,可以第一时间为您捕获生存环境中小程序的异常.错误或者BUG, ...
- Git 分支模型
翻译自:https://nvie.com/posts/a-successful-git-branching-model/ 在这篇文章中,主要介绍 Git 分支模型.不会谈论任何项目的细节,只讨论分支策 ...
- Microsoft Edge浏览器下载文件乱码修复方法(二)
之前有写过"Microsoft Edge浏览器下载文件乱码修复方法",发现很多情况下下载文件乱码问题还是存在,这里对之前内容做简单补充,希望可以帮到大家. 方法二: 默认如果提示下 ...
- REST API disable / enable service auto start by API
how to disable service auto start by API as the following how to enable service auto start by API as ...
- [Inside HotSpot] hotspot的启动流程与main方法调用
hotspot的启动流程与main方法调用 虚拟机的使命就是执行public static void main(String[])方法,从虚拟机创建到main方法执行会经过一系列流程.这篇文章详细讨论 ...