夜光序言:
那些彼此牵挂的人最后都会回到同一个星球。
正文:
以道御术 / 以术识道
package 备忘录模式.游戏角色;
//第一步
public class Originator {
private String state; //状态信息
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//编写一个方法,可以保存一个状态对象 Memento
//因此,编写一个方法,返回Memento
public Memento saveStateMemento(){
return new Memento(state);
}
//通过备忘录对象,恢复状态
public void getStateFromMemento(Memento memento){
//夜光:这里想要恢复的话
//不需要返回,只需要赋给值就行
state = memento.getState();
}
}
package 备忘录模式.游戏角色;
//第二步
public class Memento {
//肯定也会有一个状态
private String state;
//之后呢,我们写一个构造器
public Memento(String state) {
this.state = state;
}
//我们需要一个get方法,就不需要set方法了
public String getState() {
return state;
}
}
package 备忘录模式.游戏角色;
import java.util.ArrayList;
import java.util.List;
//第三步
public class CareTaker {
//在list集合中会有很多备忘录对象
private List<Memento> mementoList = new ArrayList<Memento>();
//添加
public void add(Memento memento){
mementoList.add(memento);
}
//既然有添加,那就肯定会有得到
//获取到第index个Originator 的备忘录对象(即保存状态)
public Memento get(int index){
return mementoList.get(index);
}
}
package 备忘录模式.游戏角色;
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState(" 圣者状态#1 火系");
//保存了当前的状态
careTaker.add(originator.saveStateMemento());
originator.setState(" 圣者状态#2 雷系");
careTaker.add(originator.saveStateMemento());
originator.setState(" 圣者状态#3 风系");
careTaker.add(originator.saveStateMemento());
//上面有三个状态
System.out.println("当前的状态是 =" + originator.getState());
//接下来,希望恢复到状态1
//这样写
originator.getStateFromMemento(careTaker.get(0)); //得到了
//接下来,恢复一下
System.out.println("恢复到状态1");
System.out.println("当前的状态是 =" + originator.getState());
}
}
package 解释器模式.四则运算;
import java.util.HashMap;
//第一步 夜光
//抽象类表达式
//通过hashmap 键值对 可以获取到变量的值
public abstract class Expression {
//我们先定义一个方法
//解释公式和数值,key就是公式(表达式)
//参数[a,b,c],value就是具体的值
//hashmap{a=10,b=20},
public abstract int interpreter(HashMap<String,Integer> var);
}
package 解释器模式.四则运算;
import java.util.HashMap;
//第二步
//变量的解释器
public class VarExpression extends Expression{
private String key; //key = a,b,c
public VarExpression(String key){
this.key = key;
}
//var就是前面的HashMap
//{a=10,b=20}
//interpreter 根据变量的名称,返回对应的值
@Override
public int interpreter(HashMap<String, Integer> var) {
return var.get(this.key);
}
}
package 解释器模式.四则运算;
import java.util.HashMap;
//第三步 夜光
//抽象运算符解析器这里,每个运算符都只和自己左右两个数字有关系
//但左右两个数字有可能也是一个解析的结果,无论何种类型,都是expression的实现
public class SymbolExpression extends Expression{
protected Expression left;
protected Expression right;
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
//因为SymbolExpression是让其子类来实现,因此 interpreter方法是一个空实现
//默认实现
@Override
public int interpreter(HashMap<String, Integer> var) {
return 0;
}
}
package 解释器模式.四则运算;
import java.util.HashMap;
//第四步
//加法解释器
public class AddExpression extends SymbolExpression{
public AddExpression(Expression left, Expression right) {
super(left, right);
}
//这个地方就是处理相加
//有点意思,var仍然是{a=10,b=20}
public int interpreter(HashMap<String, Integer> var) {
//这个super.left.interpreter(var) :返回left表达式对应的值 a=10
//super.right.interpreter(var):返回right表达式对应的值 b=20
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
package 解释器模式.四则运算;
import java.util.HashMap;
//第五步
//这里是减法
public class SubExpression extends SymbolExpression{
public SubExpression(Expression left, Expression right) {
super(left, right);
}
//这个地方就是处理相减
//有点意思,var仍然是{a=10,b=20}
public int interpreter(HashMap<String, Integer> var) {
//这个super.left.interpreter(var) :返回left表达式对应的值 a=10
//super.right.interpreter(var):返回right表达式对应的值 b=20
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
package 解释器模式.四则运算;
import java.util.HashMap;
import java.util.Stack;
//夜光
//第六步
public class Calculator {
//定义表达式
private Expression expression;
//构造函数传参,并且解析
public Calculator(String expStr){ //expStr = a+b-c
//安排运算先后顺序
Stack<Expression> stack = new Stack<>();
//夜光:表达式拆分成字符数组
char[] charArray = expStr.toCharArray(); //[a,+,b] 只有拆分了才可以取出a和b
Expression left = null;
Expression right = null;
//遍历我们的字符数组,即遍历[a,+,b]
//针对不同情况,做相应的处理
for (int i=0;i<charArray.length;i++){
switch (charArray[i]){
case '+':
left = stack.pop(); //从stack取出left → "a"
right = new VarExpression(String.valueOf(charArray[++i])); //取出右边的表达式 → "b"
stack.push(new AddExpression(left,right)); // + 然后根据得到的 left,right 构建 AddExpression 加入stack
break;
case '-':
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new SubExpression(left,right)); // -
break;
default:
//如果是一个 Var 就创建要给 VarExpression 对象
//并push到stack
stack.push(new VarExpression(String.valueOf(charArray[i])));
break;
}
}
//当遍历完整个charArray数组后,stack就得到最后Expression
this.expression = stack.pop();
}
//最后run一下,这个表达式
public int run(HashMap<String, Integer> var){
//最后将表达式a+b 和 var 绑定 {a=10,b=30} → var ={a=10,b=30}
//然后传递给expression的interpreter进行解释执行
return this.expression.interpreter(var);
}
}
package 解释器模式.四则运算;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
//夜光:最后我们写一个测试的客户端
public class ClienTest {
public static void main(String[] args) throws IOException {
String expStr = getExpStr(); //打个比方 a+b
HashMap<String,Integer> var = getValue(expStr); // var {a=10,b=20}
Calculator calculator = new Calculator(expStr);
System.out.println("夜光,运算结果是:" + expStr + "=" + calculator.run(var));
}
//夜光:获得表达式
private static String getExpStr() throws IOException{
System.out.println("少侠,请输入表达式:");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
//获得值映射
private static HashMap<String, Integer> getValue(String expStr) throws IOException{
HashMap<String, Integer> map = new HashMap<>();
for(char ch : expStr.toCharArray()) {
if(ch != '+' && ch != '-' ) {
if(! map.containsKey(String.valueOf(ch))) {
System.out.print("请输入" + String.valueOf(ch) + "的值:");
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
}