解释器模式 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 <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白: “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...
随机推荐
- 网页基础:网页设计(我所知道的所有的html和css代码(含H5和CSS3)),如有错误请批评指正
最基础的网页设计,就是给你一个图片你做成一个网页,当然,我的工作是C#,个人网页的功底不是很高首先先认识一下网页的一些相关知识: 一般的,现在一个html网页一般包含html文件,css文件,js文件 ...
- PHP全栈学习笔记13
php与ajax技术 web2.0的到来,ajax逐渐成为主流,什么是ajax,ajax的开发模式,优点,使用技术.(ajax概述,ajax使用的技术,需要注意的 问题,在PHP应用ajax技术的应用 ...
- 这可能是史上最好的 Java8 新特性 Stream 流教程
本文翻译自 https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ 作者: @Winterbe 欢迎关注个人微信公众 ...
- react源码总览(翻译)
用react也有段时间了, 是时候看看人家源码了. 看源码之前看到官方文档 有这么篇文章介绍其代码结构了, 为了看源码能顺利些, 遂决定将其翻译来看看, 小弟英语也是半瓢水, 好多单词得查词典, 不当 ...
- C# 通俗说 委托(和事件)
1.闲聊 编码一两年, 我走过了字段, 我跑过了类, 却翻不过方法.(不能灵活使用方法吧) (写这篇博客全程听将夜中<永夜>歌曲写完的,一气呵成,安利一下) 2.叙事 我们在编码中,经常捣 ...
- 用Docker解决坑爹的环境搭建系列——ubuntu16.04 SSH
sudo docker run --name java -d -p 19992:22 -p 9992:8080 hub.c.163.com/public/ubuntu:16.04-tools # 可以 ...
- clang如何获得程序控制流图
在低版本的clag中,可以直接clang -cc1 -analyze -cfg-dump 1.c来获得程序控制流图,但较高版本后就不行了 另外clang -cc1默认仅限当前目录,所以会出现fata ...
- Asp.Net Core Web应用程序—探索
前言 作为一个Windows系统下的开发者,我对于Core的使用机会几乎为0,但是考虑到微软的战略规划,我觉得,Core还是有先了解起来的必要. 因为,目前微软已经搞出了两个框架了,一个是Net标准( ...
- HTML5最佳实践web app
简介 本文重点关注如何充分利用HTML5和CSS让web app运行更加流畅. Tip 1: 使用web storage代替cookie cookie最大的缺陷是在每一次HTTP请求中都会携带所有符合 ...
- css控制元素高度自适应
可以采用元素定位 + padding 的方式使特定元素高度自适应. css 样式: html,body{ height:100%; margin:; padding:; } .wrap { heigh ...