解释器模式 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 <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白: “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...
随机推荐
- [翻译 EF Core in Action 2.3] 理解EF Core数据库查询
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- 『动态』动态JSON万能转换函数 + .Net40 dynamic动态数据绑定
不废话,调用代码: static void Main(string[] args) { string json = File.ReadAllText("2.txt", Encodi ...
- 一个小实例理解js 原型和继承
导语1:一个构造函数的原型对象,其实就是这个构造函数的一个属性而已,属性名叫prototype,值是一个对象,对象中有一些属性和方法,所以每个构造函数的实例对象都拥有这些属性和方法的使用权. 导语2: ...
- .NET CAD二次开发学习 对称画线功能
[CommandMethod("CBline")] //对称画线 public void CBline() { Document doc = Application.Documen ...
- c# 接口相同方法申明使用
using System; namespace ConsoleApp1 { interface IInterface1 { void ft(); } interface IInterface2 { v ...
- 怎么让DIV在另一个DIV里靠底部显示?
可以使用css的position属性的绝对定位. 拓展知识 position 属性指定了元素的定位类型. position 属性的五个值: static:HTML元素的默认值,即没有定位,元素出现在正 ...
- 记录一些flutter学习网址
字体图标生成 http://fluttericon.com/Flutter中文网 https://flutterchina.club Flutter官网 https://flutter.ioFlutt ...
- MAC中使用APICloud同步代码错误解决办法
在MAC上使用APICloud同步代码时出现错误,其实就是git位置的问题,简单点就是把路径映射下. 问题提示: Can't locate SVN/Core.pm in @INC (you may n ...
- redis cluster + sentinel详细过程和错误处理三主三备三哨兵
redis cluster + sentinel详细过程和错误处理三主三备三哨兵1.基本架构192.168.70.215 7001 Master + sentinel 27001192.168.70. ...
- linux open write lseek的API和应用
1, open #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(c ...