解释器模式 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 <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白: “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...
随机推荐
- Spark学习之RDD编程总结
Spark 对数据的核心抽象——弹性分布式数据集(Resilient Distributed Dataset,简称 RDD).RDD 其实就是分布式的元素集合.在 Spark 中,对数据的所有操作不外 ...
- 一个比喻讲明Docker是什么
之前一直听运维的同事讲Docker,说弄个Docker镜像,打包些应用什么的,还有时不时地在一些帖子里见到过关于Docker的三言两语,然后自己也自我感觉良好的把它总结归纳了一下认为:"往D ...
- 【转载】Docker+Kubernetes 干货文章精选
主要涉及到以下关键字: K8S.Docker.微服务.安装.教程.网络.日志.存储.安全.工具.CI/CD.分布式.实践.架构等: 以下盘点2018年一些精选优质文章! 漫画形式: 漫画:小黄人学 S ...
- Fastjson 1.2.22-24 反序列化漏洞分析
目录 0x00 废话 0x01 简单介绍 FastJson的简单使用 0x02 原理分析 分析POC 调试分析 0x03 复现过程 0x04 参考文章 0x00 废话 balabala 开始 0x01 ...
- SSH免密登陆原理及实现
声明:作者原创,转载注明出处. 作者:帅气陈吃苹果 一.SSH简介 SSH(Secure Shell)是一种通信加密协议,加密算法包括:RSA.DSA等. RSA:非对称加密算法,其安全性基于极其困难 ...
- Mybatis增删改查,Demo整合
第一步:MyBatis的Jar包引入mybatis-3.2.7.jarmysql-connector-java-5.1.8.jar MyBatis的pom.xml依赖 <dependencies ...
- asp.net core系列 28 EF模型配置(字段,构造函数,拥有实体类型)
一. 支持字段 EF允许读取或写入字段而不是一个属性.在使用实体类时,用面向对象的封装来限制或增强应用程序代码对数据访问的语义时,这可能很有用.无法使用数据注释配置.除了约定,还可以使用Fluent ...
- Flink源码分析 - 源码构建
原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483692&idx=1&sn=18cddc1ee ...
- 多线程总结之旅(1):线程VS进程
一.进程:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,也就是应用程序的执行实例,进程是系统进行资源分配和调度的一个独立单位.每个进程是由私有的虚拟地址空间.代码.数据和其它各种系统资 ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...