夜光带你走进 Java 成神之路(三十三)擅长的领域

夜光序言:

 

那些彼此牵挂的人最后都会回到同一个星球。

 

正文:

                           以道御术 / 以术识道

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;
    }



}
发布了1477 篇原创文章 · 获赞 281 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/weixin_41987706/article/details/103574225