4.设计模式之后七种模式后11种模式命令访问者迭代器发布订阅中介者忘备录解释器状态策略职责链和空模式

news2024/11/25 12:36:04

1.命令(command)模式 不知道命令接收者(对象)是谁,支持撤销 (接受者 间接调用执行 的具体行为) 命令调用者和接收者解耦
//只要实现命令接口即可 (就是客户端给个命令,然后命令类传给接收类执行)

  1. 优点和缺点 容易撤销操作 命令队列可以多线程操作
    增加过多的命令类
    空命令也是一种设计模式,可以减少对象判空

//具体的操作类
请添加图片描述
//命令模式实现智能家电系统
请添加图片描述

public class Light {
    public void on(){
        System.out.println("打开电灯");
    }
    public void off(){
        System.out.println("关闭电灯");
    }
}

//命令类聚合操作类

public interface Command {

    void execute();
    void undo();

}
public class LightOffCommand implements Command {
    Light light;
    LightOffCommand(Light light){
        super();
        this.light=light;
    }
    @Override
    public void execute() {
        light.off();
    }

    @Override
    public void undo() {
        light.on();
    }
}
public class LightOnCommand implements Command {
    Light light;
    LightOnCommand(Light light){
        super();
        this.light=light;
    }
    @Override
    public void execute() {
        light.on();
    }

    @Override
    public void undo() {
        light.off();
    }
}
//也是一种命令模式,用于初始化
public class NoCommand implements Command {
    @Override
    public void execute() {

    }

    @Override
    public void undo() {

    }
}

//控制所有命令的类

public class RemoteController {
    private Command onCommands[]=new Command[5];
    private Command offCommands[]=new Command[5];
    private Command undoCommand;
    public RemoteController(){
        for (int i=0;i<5;i++){
            onCommands[i]=new NoCommand();
            offCommands[i]=new NoCommand();
        }
    }
    public void setCommand(int no,Command onCommand1,Command offCommand1){
        onCommands[no]=onCommand1;
        offCommands[no]=offCommand1;
    }
    // 按下开按钮
    public void onButtonWasPushed(int no) { // no 0
        // 找到你按下的开的按钮, 并调用对应方法
        onCommands[no].execute();
        // 记录这次的操作,用于撤销
        undoCommand = onCommands[no];

    }

    // 按下开按钮
    public void offButtonWasPushed(int no) { // no 0
        // 找到你按下的关的按钮, 并调用对应方法
        offCommands[no].execute();
        // 记录这次的操作,用于撤销
        undoCommand = offCommands[no];

    }

    // 按下撤销按钮
    public void undoButtonWasPushed() {
        undoCommand.undo();
    }




}
public class Client {
    public static void main(String[] args) {
        RemoteController remoteController = new RemoteController();
        Light light = new Light();
        remoteController.setCommand(0,new LightOnCommand(light),new LightOffCommand(light));

        remoteController.onButtonWasPushed(0);
        //撤销操作
        remoteController.undoButtonWasPushed();
        remoteController.onButtonWasPushed(0);
        remoteController.offButtonWasPushed(0);

    }
}

//结果

打开电灯
关闭电灯
打开电灯
关闭电灯

2.命令模式在springjdbcTemplate的使用
JdbcTemplate类:是调用者类

public int update(final String sql) throws DataAccessException {
        Assert.notNull(sql, "SQL must not be null");
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Executing SQL update [" + sql + "]");
        }

        class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
            UpdateStatementCallback() {
            }

            public Integer doInStatement(Statement stmt) throws SQLException {
                int rows = stmt.executeUpdate(sql);    //里面是模拟接收类 具体处理业务
                if (JdbcTemplate.this.logger.isDebugEnabled()) {
                    JdbcTemplate.this.logger.debug("SQL update affected " + rows + " rows");
                }

                return rows;
            }

            public String getSql() {
                return sql;
            }
        }

        return (Integer)this.execute((StatementCallback)(new UpdateStatementCallback()));
    }
 StatementCallback接口:命令类接口 
  public interface StatementCallback<T> {
    T doInStatement(Statement var1) throws SQLException, DataAccessException;
}
//内部类StatementCallback:命令接受者(实际的动作)

2.访问者(visitor)模式

  1. 原理: 让被访问的类加个对外访问接待的接口,避免不同操作(没有关系)污染访问者类
    双分派,第一次参数以类的父类的形式传入方法,第二次用this传入父类的方法
    只要加入一个Action就可以不用改其他代码
  2. 优点和缺点 符合单一职责模式, 可做报表 ui 拦截器和过滤器,适合数据结构相对比较稳定的
    缺点: 违反迪米特法则(访问者关注了其他类的内部细节)
    违反了依赖倒转原则(具体元素对访问者要公开,是抽象而不是具体的类)
    原理图
    请添加图片描述
    请添加图片描述

//核心类者类有个 接收操作的参数

public abstract class Action {
    public abstract void  getWomanResult(WoMan woMan);
    public abstract void  getManResult(Man men);
}
public class Fail extends Action{

    @Override
    public void getWomanResult(WoMan woMan) {
        System.out.println("女人"+ woMan.name+"评价差评");
    }

    @Override
    public void getManResult(Man men) {
        System.out.println("男人"+ men.name+"评价差评");
    }
}
public class NoGood extends Action{

    @Override
    public void getWomanResult(WoMan woMan) {
        System.out.println("女人"+ woMan.name+"评价待定");
    }

    @Override
    public void getManResult(Man men) {
        System.out.println("男人"+ men.name+"评价待定");
    }
}
public class Sucess extends Action{

    @Override
    public void getWomanResult(WoMan woMan) {
        System.out.println("女人"+woMan.getName()+"评价点赞");
    }

    @Override
    public void getManResult(Man men) {
        System.out.println("男人"+men.getName()+"评价点赞");
    }
}




//访问者类 核心类
public abstract class  Person
 {
    abstract void accept(Action action);
}
public class Man extends Person {
    public String name;
    @Override
    void accept(Action action) {
        action.getManResult(this);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class WoMan extends Person {
    public String name;
    @Override
    void accept(Action action) {
        action.getWomanResult(this); //双分派用this,知道本对象的类型
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

//元素类可以用来管理,有点像组件模式的管理者类,但是不用继承

  public class ElementStructure {
    Map<Person, Action> maps= new HashMap<Person,Action>();
    public void addList(Person person,Action action){
        maps.put(person,action);
    }
    public void removeList(Person person){
        maps.remove(person);
    }
    public void print(){
      maps.forEach(new BiConsumer<Person, Action>() {
          @Override
          public void accept(Person person, Action action) { //person违反依赖倒转原则
              if(person instanceof Man){//知道了其他类的信息,new 
                  action.getManResult((Man)person);   
              }
              if(person instanceof WoMan){
                  action.getWomanResult((WoMan)person);
              }

          }
      });
    }


}

//测试

public class Client {
    public static void main(String[] args) {
        ElementStructure elementStructure = new ElementStructure();
        Man man = new Man();
        man.setName("aa");
        elementStructure.addList(man,new Sucess());
        WoMan woMan = new WoMan();
        woMan.setName("bb");
        elementStructure.addList(woMan,new Fail());
        WoMan woMan1 = new WoMan();
        woMan1.setName("cc");
        elementStructure.addList(woMan1,new NoGood());

        elementStructure.print();

    }
}

3.迭代器模式(工作用得多) 统一遍历的方式 数组还是集合还是其他(链表…)格式(添加到集合也是聚合组合)

  1. 先实现Iterator类,然后进行构建不同方式遍历,返回给客户端迭代器对象
  2. 优点缺点 单一职责原则,但每个类都要一个迭代器不好管理
    //迭代器原理请添加图片描述
    //实现院系和专业的深度遍历原理图
    请添加图片描述

//先创建要迭代的对象

public class Department {

    private String name;
    private String desc;
    public Department(String name, String desc) {
        super();
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

public interface Colleage {

    Iterator createInterator();
    void add(String name,String res);
    void remove();
    String getName();

}
public class ComputerColeage implements Colleage {
    public String name="计算机学院";
    Department []departments;
    //遍历的下标
    int index=-1;
    //长度
    int length=-1;
    public ComputerColeage(){
        departments=new Department[5];
    }
    public void add(String name,String res){
        length++;
        departments[length]=new Department(name,res);

    }
    //空实现
    public void remove(){

    }
    @Override
    public Iterator createInterator() {
        return new ComputerCollegeIterator(departments,length);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class InfoColeage implements Colleage {
    public String name="信息学院";
    List infoList;


    public InfoColeage(){
        infoList=new ArrayList();
    }
    public void add(String name,String res){
        infoList.add(new Department(name,res));

    }
    //空实现
    public void remove(){

    }
    @Override
    public Iterator createInterator() {
        return new InfoCollegeIterator(infoList);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

//核心步骤,创建迭代器实现Iterator接口实现方法
//存储结构决定迭代方式

public class ComputerCollegeIterator implements Iterator {
    Department []departments;
    //遍历的下标
    int index=-1;
    //长度
    int length=-1;
    public ComputerCollegeIterator(Department []departments, int length){
        this.departments=departments;
        this.length=length;

    }
    @Override
    public boolean hasNext() {
        if(index+1 > length||departments[index+1]==null){
            return false;
        }
        return true;
    }

    @Override
    public Department next() {
        if (hasNext()){
            index++;
            return departments[index];
        }
        return null;
    }
}


//另外一个使用list结构
public class InfoCollegeIterator implements Iterator {
    List<Department> infoList;
    //遍历的下标
    int index=-1;
    //长度
    int length=-1;
    public InfoCollegeIterator(List<Department> infoList){
        this.infoList=infoList;


    }
    @Override
    public boolean hasNext() {
        if(index+1 >= infoList.size()){
            return false;
        }
        return true;
    }

    @Override
    public Department next() {
        Department department;
        if (hasNext()){
            index++;
            return infoList.get(index);
        }


        return null;

    }
}
//专门打印的类
public class OutputImpl  {
    Iterator<Colleage> iterator;
    OutputImpl(List<Colleage> list){
        iterator = list.iterator();
    }
   //打印学院
    void printList(){
        while (iterator.hasNext()){

            Colleage colleage = iterator.next();
            System.out.println("--------------"+colleage.getName()+"--------------");
            Iterator it = colleage.createInterator();
            printDepartment(it);

        }
    }
   //打印学院下的专业
    void printDepartment(Iterator it){
        while (it.hasNext()){
            component.Department next = (Department) it.next();
            System.out.println(next.getName());


        }

    }
}

//测试类


 - public class Client {
       public static void main(String[] args) {
           List list=new ArrayList<Colleage>();
           Colleage computerColeage = new ComputerColeage();
           computerColeage.add("软件工程专业","软件工程专业");
           computerColeage.add("网络工程专业","网络工程专业");
           list.add(computerColeage);
           Colleage  infoColeage= new InfoColeage();
           infoColeage.add("信息工程专业","信息工程专业");
           infoColeage.add("网络安全工程专业","网络安全专业");
           list.add(infoColeage);
           OutputImpl output = new OutputImpl(list);
           output.printList();
   
   
   
       } } 

4.迭代器模式jdk源码Arraylist继承List得到迭代器对象方法 Itr具体实现迭代器
请添加图片描述

    List list=new ArrayList<Colleage>();
    list.iterator();
   // ArrayList有方法,Itl是迭代器实现类
    public Iterator<E> iterator() {
        return new Itr();
    }

5.观察者(observer)模式 Subject( 一)对 Observer(用户 多) 就是发布订阅模式

当数据发生改变时通知所有接入方,也可以移除,通知者就变少了
subject: add delete notify…
observer: update
天气预报项目,方便其他第三方接入 //无论是什么设计模式都先写实体类,就是在实体类分开职责和学习设计模式其实就是学习加强的java高级的理解(map,list在哪些方面可以使用)
请添加图片描述

public interface SubjectWeather {
    public void registerUser(Observer observer);
    public void removeUser(Observer observer);
    public void notifyUser();
    public void setData(float centigrade,float humidity);

}

public class WeatherData implements SubjectWeather{
    float centigrade=0;
    float humidity=0;
    ArrayList<Observer> list=new ArrayList<>();



    @Override
    public void registerUser(Observer observer) {
        list.add(observer);
    }

    @Override
    public void removeUser(Observer observer) {
        list.remove(observer);
    }

    @Override
    public void notifyUser() {
        for (int i=0;i<list.size();i++){
            list.get(i).update(this);

        }
    }

    @Override
    public void setData(float centigrade, float humidity) {
        this.centigrade=centigrade;
        this.humidity=humidity;
        notifyUser();
    }
}

//写观察者,就是可以通知到的对象

public interface Observer {
    public  void update(WeatherData weatherDate);
}
//给其他网站数据
public class BaiduWeatherObserver implements Observer{
    @Override
    public void update(WeatherData weatherData) {
        System.out.println("百度调用 今天温度:"+weatherData.centigrade+"湿度:"+weatherData.humidity);
    }
}
public class XinlangWeatherObserver implements Observer{
    @Override
    public void update(WeatherData weatherData) {
        System.out.println("新浪调用 今天温度:"+weatherData.centigrade+"湿度:"+weatherData.humidity);
    }
}

//测试

public class Client {
    public static void main(String[] args) throws InterruptedException {
        WeatherData weatherData = new WeatherData();
        weatherData.registerUser(new BaiduWeatherObserver());
        weatherData.registerUser(new XinlangWeatherObserver());
        weatherData.setData(10f,20f);


        Thread.sleep(2000);

        weatherData.setData(20.2f,20f);



    }
}

//运行结果

百度调用 今天温度:10.0湿度:20.0
新浪调用 今天温度:10.0湿度:20.0
百度调用 今天温度:20.2湿度:20.0
新浪调用 今天温度:20.2湿度:20.0

6.观察者在jdk源代码Observable类(直接是观察者不用实现接口)的使用 直接
想要使用观察者直接继承Observale
//subject,被观察者

public class Observable { //整个线程是安全的
    private boolean changed = false;
    private Vector<Observer> obs;   //和我们上面的list一样,这个是线程安全的

    /** Construct an Observable with zero Observers. */

    public Observable() {
        obs = new Vector<>();
    }


    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    /**
     * Deletes an observer from the set of observers of this object.
     * Passing <CODE>null</CODE> to this method will have no effect.
     * @param   o   the observer to be deleted.
     */
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }


    public void notifyObservers() {
        notifyObservers(null);
    }


    public void notifyObservers(Object arg) {
        /*
         * a temporary array buffer, used as a snapshot of the state of
         * current Observers.
         */
        Object[] arrLocal;

        synchronized (this) {
            /* We don't want the Observer doing callbacks into
             * arbitrary code while holding its own Monitor.
             * The code where we extract each Observable from
             * the Vector and store the state of the Observer
             * needs synchronization, but notifying observers
             * does not (should not).  The worst result of any
             * potential race-condition here is that:
             * 1) a newly-added Observer will miss a
             *   notification in progress
             * 2) a recently unregistered Observer will be
             *   wrongly notified when it doesn't care
             */
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    /**
     * Clears the observer list so that this object no longer has any observers.
     */
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    /**
     * Marks this <tt>Observable</tt> object as having been changed; the
     * <tt>hasChanged</tt> method will now return <tt>true</tt>.
     */
    protected synchronized void setChanged() {
        changed = true;
    }

    /**
     * Indicates that this object has no longer changed, or that it has
     * already notified all of its observers of its most recent change,
     * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
     * This method is called automatically by the
     * <code>notifyObservers</code> methods.
     *
     * @see     java.util.Observable#notifyObservers()
     * @see     java.util.Observable#notifyObservers(java.lang.Object)
     */
    protected synchronized void clearChanged() {
        changed = false;
    }

    /**
     * Tests if this object has changed.
     *
     * @return  <code>true</code> if and only if the <code>setChanged</code>
     *          method has been called more recently than the
     *          <code>clearChanged</code> method on this object;
     *          <code>false</code> otherwise.
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#setChanged()
     */
    public synchronized boolean hasChanged() {
        return changed;
    }

    /**
     * Returns the number of observers of this <tt>Observable</tt> object.
     *
     * @return  the number of observers of this object.
     */
    public synchronized int countObservers() {
        return obs.size();
    }
}

//观察者

   public interface Observer {
    void update(Observable o, Object arg);
}

7.中介者(mediator)模式(行为模式) 避免多对多关系相互调用,使用中介一对多集中同一管理 子系统解耦

  1. MVC模式 view去调用controller调用多个model/dao处理业务
    Mediator调用同事的关系和同事类Coleague管理其他关系和得到Mediotor类
  2. 优点和缺点 类的网状结构转变为星型结构 符合迪米特法则,但中介者出现问题,整个系统受影响
    设计不当中介者对象会变得复杂请添加图片描述
    //中介者模式实现家居管理系统
    请添加图片描述

//中介者

public abstract class Mediator {
   abstract String getMessage(String str);
    abstract String sendMessageToTV(String str);
   abstract void registerColleague(String name,Colleague colleague);
    abstract void removeColleague(String name);


}

//中介者实现类

public class ConcreteMeditor extends Mediator {
    Map map=new HashMap<String,Colleague>();
    @Override
    String getMessage(String name) {
        String str="中介得到信息"+name;
        System.out.println(str);
        return str;
//        Colleage colleage=(Colleage)(map.get(str));
//        if(colleage instanceof ){
//
//
//        }
    }

    @Override
    String sendMessageToTV(String str) {
        System.out.println("中介接收到消息"+str);
       Tv tv=(Tv)(map.get("电视"));


            tv.sendStatueToTV(str);


        return null;
    }

    @Override
    void registerColleague(String name,Colleague colleague) {
        map.put(name,colleague);
    }

    @Override
    void removeColleague(String name) {
        map.remove(name);
    }
}

//同事类

public abstract class Colleague {
    abstract void sendStatue();
    abstract void sendStatueToTV();
    abstract void sendStatueToTV(String str);
}
//同事类的子类
public class Tv extends Colleague {
    Mediator mediator;
    Tv(Mediator mediator){
        this.mediator=mediator;
    }
    @Override
    void sendStatue() {
        System.out.println("电视发送消息成功");
        String msg = mediator.getMessage("法外狂徒张三");


    }

    @Override
    void sendStatueToTV() {


    }

    @Override
    void sendStatueToTV(String str) {
        System.out.println("tv接收到消息:"+str);

    }
}
public class Projector extends Colleague {
    Mediator mediator;
    Projector(Mediator mediator){
        this.mediator=mediator;
    }
    @Override
    void sendStatue() {
        System.out.println("投影仪发送消息成功");
        String msg = mediator.getMessage("法外狂徒张三");
    }

    @Override
    void sendStatueToTV() {
        System.out.println("投影仪向tv发出信息");
        mediator.sendMessageToTV("你好tv我是projector");
    }

    @Override
    void sendStatueToTV(String str) {

    }


}

//测试类

public class Client {
    public static void main(String[] args) {

        Mediator concreteMeditor = new ConcreteMeditor();
        Colleague tv = new Tv(concreteMeditor);
        Projector projector = new Projector(concreteMeditor);
        concreteMeditor.registerColleague("电视",tv);
        concreteMeditor.registerColleague("投影仪",projector);
        tv.sendStatue();
        projector.sendStatue();
        projector.sendStatueToTV(); //projector通过中介向tv发送消息!!!
    }

}

//运行结果

电视发送消息成功
中介得到信息法外狂徒张三
投影仪发送消息成功
中介得到信息法外狂徒张三
投影仪向tv发出信息
中介接收到消息你好tv我是projector
tv接收到消息:你好tv我是projector

8.备忘录(memento)模式(传统模式new处理备份) (回退 行为模式)备份原来对象的属性到另外一个对象,原来状态以后可以恢复请添加图片描述

  1. originator(发起人) 有备份方法和(客户端给备忘录对象)回退原来memento数据方法,可以保存多个忘备录对象
  2. memento(备份对象) caretaker 保存维护一个/多个memento对象

//发起人
//王者荣耀的盖伦的状态

public class GaiLun {
    //速度
    private int speed;
    //攻击力
    private int hit;


    //设置备忘录类,备份盖伦的属性
    public Memento createMenento(){
        return new Memento(speed,hit);
    }
    //恢复第一个状态,也可以根据自己的需要改成回退上一个状态
    public void back(TakeCarer carer){
        Memento memento = carer.getList().get(0);
        speed=memento.getSpeed();
        hit=memento.getHit();

    }
    public void display(){
        System.out.println("---速度:"+speed+"攻击:"+hit+"----");
    }


    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getHit() {
        return hit;
    }

    public void setHit(int hit) {
        this.hit = hit;
    }
}

//备忘录类,设计号要备份的属性

public class Memento {
    //速度
    private int speed;
    //攻击力
    private int hit;
    Memento(int speed,int hit){
        this.speed=speed;
        this.hit=hit;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getHit() {
        return hit;
    }

    public void setHit(int hit) {
        this.hit = hit;
    }
}

//维护多个备忘录类

public class TakeCarer {
    ArrayList<Memento> list=new ArrayList<>();
    public void register(Memento memento){
        list.add(memento);
    }
    public void remove(Memento memento){
        list.remove(memento);
    }

    public ArrayList<Memento> getList() {
        return list;
    }

    public void setList(ArrayList<Memento> list) {
        this.list = list;
    }
}

//测试类

public class Client {
    public static void main(String[] args) {
        GaiLun gaiLun = new GaiLun();
        gaiLun.setSpeed(100);
        gaiLun.setHit(0);
        System.out.println("------战斗前-----");
        Memento menento = gaiLun.createMenento();
        TakeCarer takeCarer = new TakeCarer();
        takeCarer.register(menento);
        gaiLun.display();
        System.out.println("------按下Q 战斗-----");
        gaiLun.setSpeed(100);
        gaiLun.setHit(20);
        gaiLun.display();
        System.out.println("------战斗后恢复状态-----");
        gaiLun.back(takeCarer);
        gaiLun.display();
    }
}

//结果

------战斗前-----
---速度:100攻击:0----
------按下Q 战斗-----
---速度:100攻击:20----
------战斗后恢复状态-----
---速度:100攻击:0----

9.备忘录的注意事项

  1. 用户不需要关心保存的细节,但类成员变量太多每次保存需要耗费内存
  2. 应用场景 后悔药 ctrl+z 打游戏时的存档,ie的回退 数据库的事务管理
  3. 和原型模式(对象的浅拷贝和深拷贝)配合使用,可以节省内存

10.解释器(interpreter)模式 和编译原理有关 根据表达式(字符串)构建语法树(加表达式复杂),进行对应的操作
//应用场景 编译器 运算表达式 正则表达式!!! 机器人,但是导致类爆炸和递归调用导致调试复杂
//图58
请添加图片描述
请添加图片描述
请添加图片描述

//四则运算运算器代码
//建立抽象表达式类,定义想要的操作

public abstract class Expression {
	// a + b - c
	// 解释公式和数值, key 就是公式(表达式) 参数[a,b,c], value就是就是具体值
	// HashMap {a=10, b=20}
	public abstract int interpreter(HashMap<String, Integer> var);
}

//创建子类

public class VarExpression extends Expression {

	private String key; // key=a,key=b,key=c

	public VarExpression(String key) {
		this.key = key;
	}

	// var 就是{a=10, b=20}
	// interpreter 根据 变量名称,返回对应值
	@Override
	public int interpreter(HashMap<String, Integer> var) {
		return var.get(this.key);
	}
}
//符号,如-号 +号
public class SubExpression extends SymbolExpression {

	public SubExpression(Expression left, Expression right) {
		super(left, right);
	}

	//求出left 和 right 表达式相减后的结果
	public int interpreter(HashMap<String, Integer> var) {
		return super.left.interpreter(var) - super.right.interpreter(var);
	}
}
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) {
		// TODO Auto-generated method stub
		return 0;
	}
}

public class AddExpression extends SymbolExpression  {

	public AddExpression(Expression left, Expression right) {
		super(left, right);
	}

	//处理相加
	//var 仍然是 {a=10,b=20}..
	//一会我们debug 源码,就ok
	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);
	}
}

public class SubExpression extends SymbolExpression {

	public SubExpression(Expression left, Expression right) {
		super(left, right);
	}

	//求出left 和 right 表达式相减后的结果
	public int interpreter(HashMap<String, Integer> var) {
	     //会不停递归interpreter函数
		return super.left.interpreter(var) - super.right.interpreter(var);
	}
}

//核心的计算类,根据表达式的不同执行不同的操作,不局限于四则运算

public class Calculator {

	// 定义表达式
	private Expression expression;

	// 构造函数传参,并解析
	public Calculator(String expStr) { // expStr = a+b
		// 安排运算先后顺序
		Stack<Expression> stack = new Stack<>();
		// 表达式拆分成字符数组 
		char[] charArray = expStr.toCharArray();// [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 构建 AddExpresson加入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();
	}

	public int run(HashMap<String, Integer> var) {
		//最后将表达式a+b和 var = {a=10,b=20}
		//然后传递给expression的interpreter进行解释执行
		return this.expression.interpreter(var);
	}
}

//测试类

public class ClientTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		String expStr = getExpStr(); // a+b
		HashMap<String, Integer> var = getValue(expStr);// var {a=10, b=20}
		//处理表达式和对应的值
		Calculator calculator = new Calculator(expStr);
		int run = calculator.run(var);
		System.out.println("运算结果:" + expStr + "=" + run);
	}

	// 获得表达式
	public static String getExpStr() throws IOException {
		System.out.print("请输入表达式:");
		return (new BufferedReader(new InputStreamReader(System.in))).readLine();
	}

	// 获得值映射
	public 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;
	}
}

11.解释器在spring的SpelExpressionParser的使用

    
是抽象表达式SpelExpressionLiteralExpression是实现的解析表达式的类
  SpelExpressionParser parser = new SpelExpressionParser();
        SpelExpression spelExpression = (SpelExpression) parser.parseExpression("10+2-1");
        Object value = spelExpression.getValue();
        System.out.println(value);

12.状态(State)模式(非常有价值的模式) 对象内有多个状态可以相互转换(有对应操作)比如抽奖
//又是聚合抽象状态 到活动类(每状态分别写为类,聚合去修改)
//要先分析出状态转换图
//解决的问题: 可读性高,方便维护.符合开闭原则和解决if-else判断混乱的问题,但类爆炸状态不好管理
请添加图片描述

//60状态模式抽奖
请添加图片描述//61状态模式电商状态转移设计
请添加图片描述
//62状态模式电商状态转移

请添加图片描述
//63状态模式电商状态转移
请添加图片描述

//回忆当年经典CF抽奖程序

//模拟CF抽奖状态变化

public abstract class State {
    //扣除Q币
    public abstract void dispenseQB();

    //开始抽奖
    public abstract void start();
    //抽奖结果
    public abstract void starting();

    //发放奖品
    public abstract void givePrice();


}
//最开始的状态
public class InitState extends State {
    Context context;

    public InitState(Context context){
        this.context=context;
    }
    //扣除Q币
    public void dispenseQB(){
        //模拟QB扣除结果
        int res=1;
        if(res==1){
            System.out.println("开始扣除10QB");
            System.out.println("扣除成功");
            context.setCount(context.getCount()+1);
            context.setState(new QBHasCostState(context));
        }else{
            System.out.println("开始扣除10QB");
            System.out.println("扣除失败");
            context.setState(new NoQBState(context));
        }



    };

    //开始抽奖
    public void start(){
        if(context.getCount()>=1){
            context.setState(new QBHasCostState(context));
        }
    };
    //抽奖结果
    public void starting(){
        System.out.println("需要先扣Q币");
    }

    @Override
    public void givePrice() {
        System.out.println("你的次数不足");
    }

    ;
    //中奖但是奖品没有库存,等待补货
    public void noPrice(){
        System.out.println("需要先扣Q币");
    };
}
//已经扣除qb了,可以选择抽奖或者继续增加抽奖次数
public class QBHasCostState extends State {
    Context context;

    QBHasCostState(Context context){
        this.context=context;
    }
    @Override
    public void dispenseQB() {
        //模拟QB扣除结果
        int res=1;
        if(res==1){
            System.out.println("开始扣除10QB");
            System.out.println("扣除成功");
            context.setCount(context.getCount()+1);
            context.setState(new QBHasCostState(context));
        }else{
            System.out.println("开始扣除10QB");
            System.out.println("扣除失败");
            context.setState(new NoQBState(context));
        }

    }


    //开始抽奖
    @Override
    public void start() {
        if(context.getCount()>=1){
            //扣除抽奖次数
            context.setCount( context.getCount()-1);
            Random random = new Random();

            String prize[]= new String[]{"雷神","黑龙(7天)","没有中奖","激浪手雷","水晶M4A1","没有中奖","激浪烟雾弹(7天)","黄金AK(7天)","5号背包(30天)","潘多拉(30天)"};
            int i = random.nextInt(10);
            if(!prize[i].equals("没有中奖")){
                System.out.println("恭喜抽中"+prize[i]);
                context.setState(new GivePrizeState(context));

            }else {
                System.out.println("很遗憾没有中奖");
                context.setState(new RaffleNoPrizeState(context));
            }


        }
    }

    @Override
    public void starting() {
        System.out.println("请先抽奖");
    }

    @Override
    public void givePrice() {
        System.out.println("请先抽奖");
    }


}

//抽到奖品
public class RafflePrizeState extends State {
    Context context;

    RafflePrizeState(Context context){
        this.context=context;
    }

    @Override
    public void dispenseQB() {
        context.setState(new InitState(context));
        context.getState().dispenseQB();
    }



    @Override
    public void start() {
        context.setState(new InitState(context));
        context.getState().start();
    }

    @Override
    public void starting() {
        context.setState(new InitState(context));
        context.getState().starting();
    }

    @Override
    public void givePrice() {
        context.setState(new InitState(context));
        context.getState().givePrice();
    }

}

//没有抽到奖品
public class RaffleNoPrizeState extends State {
    Context context;

    RaffleNoPrizeState(Context context) {
        this.context = context;
    }

    @Override
    public void dispenseQB() {
        context.setState(new InitState(context));
    }


    @Override
    public void start() {
        context.setState(new InitState(context));
    }

    @Override
    public void starting() {
        context.setState(new InitState(context));
    }

    @Override
    public void givePrice() {
        context.setState(new InitState(context));
    }
}

//抽到奖品
public class RafflePrizeState extends State {
    Context context;

    RafflePrizeState(Context context){
        this.context=context;
    }

    @Override
    public void dispenseQB() {
        context.setState(new InitState(context));
        context.getState().dispenseQB();
    }



    @Override
    public void start() {
        context.setState(new InitState(context));
        context.getState().start();
    }

    @Override
    public void starting() {
        context.setState(new InitState(context));
        context.getState().starting();
    }

    @Override
    public void givePrice() {
        context.setState(new InitState(context));
        context.getState().givePrice();
    }

}

//context类,放其他需要的资源 比如抽奖次数
public class Context {
    State state;
    //抽奖次数
    public int count=0;
    Context(){

    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}
public class Client {
    public static void main(String[] args) {

        Context context=new Context();

        InitState initState = new InitState(context);
        context.setState(initState);
        context.getState().dispenseQB();
        System.out.println("现在抽奖次数"+context.getCount());
        context.getState().start();
        context.getState().givePrice();

        context.getState().dispenseQB();
        context.getState().start();





    }
}

//程序运行结果

开始扣除10QB
扣除成功
现在抽奖次数1
很遗憾没有中奖
开始扣除10QB
扣除成功
恭喜抽中5号背包(30)

13.策略(stategy,行为!!!拆分)模式 将继承换成组合和聚合行为到资源类,面向接口,(继承需要所有子类实现,但是如果不需要所有方法,需要全部覆盖)
//需要分析项目变化部分和不变部分,符合开闭原则 (策略多则类多,但是解决问题必然产生大量的类然后比较好管理)
64策略模式电商鸭子案例

请添加图片描述

//行为类
//策略模式模拟穿越火线武器功能
// 武器有近身武器和投掷武器和远程射击武器

public interface Weapon {
    public void attack();
    public void discard();
}
//近战攻击
public class CloseAttack implements Weapon{
    @Override
    public void attack() {
        System.out.println("可以近战攻击");
    }
    public void discard(){
        System.out.println("不可丢弃");
    }
}
//投掷物攻击
public class FlingAttack implements Weapon{

        @Override
        public void attack() {
            System.out.println("可以投掷");
        }

    @Override
    public void discard() {
        System.out.println("按G不可丢弃,只可投掷");
    }
}
//远程攻击
public class RemoteAttack implements Weapon{
    @Override
    public void attack() {
        System.out.println("可以远程发射子弹");
    }

    @Override
    public void discard() {
        System.out.println("可以丢弃");
    }
}

//新版本cf有角色可以踢腿和不可踢腿

public interface RoleAction {
    public void CanRiseUPFoot();
}
//飞虎队不可以踢腿
public class FHDRoleAction implements RoleAction {
    @Override
    public void CanRiseUPFoot() {
        System.out.println("飞虎队不可以踢腿");
    }
}

//审判者可以踢腿
public class JudgerRoleAction implements RoleAction {
    @Override
    public void CanRiseUPFoot() {
        System.out.println("审判者按E可以踢腿");
    }
}

//资源类

public class GameProperties {
   //资源行为
    Weapon weapon;
    RoleAction role;
    GameProperties(Weapon weapon,RoleAction role){
        this.weapon=weapon;
        this.role=role;
    }
    public void attack(){
        weapon.attack();
    }
    public void riseUpFoot(){
        role.CanRiseUPFoot();
    }
}

//测试类

public class Client {
    public static void main(String[] args) {
        GameProperties gameProperties = new GameProperties(new CloseAttack(), new FHDRoleAction());
        gameProperties.attack();
        gameProperties.riseUpFoot();
        GameProperties gameProperties1 = new GameProperties(new FlingAttack(), new JudgerRoleAction());
        gameProperties1.attack();
        gameProperties1.riseUpFoot();

    }
}

//运行结果

可以近战攻击
飞虎队不可以踢腿
可以投掷
审判者按E可以踢腿

14.策略模式在jdk的Arrays.sort()的使用
Comparator是策略接口
Arrays.sort()是资源类

   Comparator<Integer> integerIntegerComparator = new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {
                if(o1>o2){
                    return 1;
                }
                return -1;
            }
        };

        Arrays.sort(integers,integerIntegerComparator);
        for (Integer integer:integers){
            System.out.println(integer);
        }
//sort方法
     public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);   //是策略之一,说明策略模式可以在客户端的处理函数或者步骤传到内部,然后内部选择策略处理
            else                               //Arrays根本没有聚合,但是通过构造函数也可以聚合到内部
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }
//方式2lambda实现

//震惊,函数式接口有一个未实现的方法,但是可以有多个static和 default方法(太6了)还有一个是equals是覆盖父类的

@FunctionalInterface
public interface Comparator<T> {

    int compare(T o1, T o2);


    boolean equals(Object obj);

   
    default Comparator<T> thenComparing(Comparator<? super T> other) {
        Objects.requireNonNull(other);
        return (Comparator<T> & Serializable) (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }


    default <U> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    {
        return thenComparing(comparing(keyExtractor, keyComparator));
    }


    default <U extends Comparable<? super U>> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        return thenComparing(comparing(keyExtractor));
    }


    default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
        return thenComparing(comparingInt(keyExtractor));
    }


    default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
        return thenComparing(comparingLong(keyExtractor));
    }


    default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
        return thenComparing(comparingDouble(keyExtractor));
    }

    public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
        return Collections.reverseOrder();
    }

    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
    }


    public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(true, comparator);
    }


    public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(false, comparator);
    }

   
    public static <T, U> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    {
        Objects.requireNonNull(keyExtractor);
        Objects.requireNonNull(keyComparator);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                              keyExtractor.apply(c2));
    }

  
    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

 
    public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
    }

  
    public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
    }

 
    public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
    }
}

15.职责链(chain of responsibility)模式 自己聚合自己(如果处理不了,由下一个自己的对象处理)(形成一条链)(行为模式) 避免请求和处理强耦合(形成环状,让任何一个人处理都能找到对应的人处理)
(目标是消灭if else因为更改需要不停变化) 图

  1. 优缺点 对象不需要找到链结构,但是链可能过长影响性能,需要设置阈值,setNext()判断是否超出,以防退化为链表
  2. 应用场景 多个对象处理同个请求 多级请求.请假/加薪等审批流程 tomcat的encoding的处理,拦截器

//OA系统审批系统, 学生请假如果申请2天 由辅导员审批.申请2天以上7天以下教导主任审批.7天以上院长审批
请添加图片描述

public abstract class Dealer {
    abstract public void  deal(String stuName,int days);
}
//辅导员
public class Assitant extends Dealer {
    //下一个处理者
    Dealer nextDealer;
    LeaveProp leaveProp;

    public Assitant(LeaveProp prop){
        this.leaveProp=prop;
    }
    @Override
    public void deal(String stuName,int days) {
        if(days<=2){
            System.out.println("辅导员处理了"+stuName+"的"+days+"天请假");
        }else{
            nextDealer.deal(stuName,days);
        }

    }

    public Dealer getNextDealer() {

        return nextDealer;
    }

    public void setNextDealer(Dealer nextDealer) {
        leaveProp.currentCount++;
        if (leaveProp.currentCount>=leaveProp.maxCout){
            System.out.println("职责链过长");

        }
        this.nextDealer = nextDealer;
    }
}
//教导主任
public class Director extends Dealer {
    //下一个处理者
    Dealer nextDealer;
    LeaveProp leaveProp;

    public Director(LeaveProp prop){
        this.leaveProp=prop;
    }
    @Override
    public void deal(String stuName,int days) {
        if(days>2 && days<=7){
            System.out.println("教导主任处理了"+stuName+"的"+days+"天请假");
        }else{
            nextDealer.deal(stuName,days);
        }

    }

    public Dealer getNextDealer() {

        return nextDealer;
    }

    public void setNextDealer(Dealer nextDealer) {
        leaveProp.currentCount++;
        if (leaveProp.currentCount>=leaveProp.maxCout){
            System.out.println("职责链过长");

        }
        this.nextDealer = nextDealer;
    }
}
//院长
public class President extends Dealer {
    //下一个处理者
    Dealer nextDealer;

   LeaveProp leaveProp;

    public President(LeaveProp prop){
        this.leaveProp=prop;
    }

    @Override
    public void deal(String stuName,int days) {
        if(days>7){
            System.out.println("院长处理了"+stuName+"的"+days+"天请假");
        }else{
            nextDealer.deal(stuName,days);
        }

    }

    public Dealer getNextDealer() {

        return nextDealer;
    }

    public void setNextDealer(Dealer nextDealer) {
        leaveProp.currentCount++;
        System.out.println(leaveProp.currentCount);
        if (leaveProp.currentCount>=leaveProp.maxCout){
            System.out.println("职责链过长");

        }
        this.nextDealer = nextDealer;
    }
}

//请假类
//请假的其他参数

public class LeaveProp {
    //设置职责链的长度
    public int maxCout=3;
    //当前职责链长度
    public int currentCount=0;
}
public class Leave {
    //学生姓名
    private String stuName;
    //请假日期
    private int leaveDays;



    Dealer dealer;
    Leave(String stuName, int leaveDays, Dealer dealer){
        this.stuName=stuName;
        this.leaveDays=leaveDays;
        this.dealer=dealer;
    }

    public void askforLeave(){
        dealer.deal(stuName,leaveDays);
    }

}

//测试类

public class Client {
    public static void main(String[] args) {

        LeaveProp leaveProp = new LeaveProp();
        Assitant assitant = new Assitant(leaveProp);
        Director director = new Director(leaveProp);
        President president = new President(leaveProp);
        //形成环状,当然也可以链尾通知不能处理
        assitant.setNextDealer(director);
        director.setNextDealer(president);
        president.setNextDealer(assitant);
        //环状导致处理可以遍历所有可处理的节点

        Leave jams = new Leave("jams", 1,president);
        jams.askforLeave();//教导主任处理了jams的3天请假
        Leave jams1 = new Leave("jams", 8,assitant);
        jams1.askforLeave();//教导主任处理了jams的3天请假

    }
}

//运行结果

3
职责链过长
辅导员处理了jams的1天请假
院长处理了jams的8天请假

16.职责链在springmvc过滤器的使用
//springMVC的架构图
请添加图片描述

DispatcherServlet的doDispatch方法有个HandlerExecutionChain使用applyPreHandle
applyPostHandle triggerAfterCompletion

//配合适配器模式,规范了处理流程

   new DispatchServlet1().doDispatch();
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;  //职责链核心
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = processedRequest != request;

				// Determine handler for the current request.
				mappedHandler = getHandler(processedRequest); //插入处理的请求对象得到处理器
				if (mappedHandler == null || mappedHandler.getHandler() == null) {
					noHandlerFound(processedRequest, response);
					return;
				}

				// Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				// Process last-modified header, if supported by the handler.
				String method = request.getMethod();
				boolean isGet = "GET".equals(method);
				if (isGet || "HEAD".equals(method)) {
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (logger.isDebugEnabled()) {
						String requestUri = urlPathHelper.getRequestUri(request);
						logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
					}
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}

				if (!mappedHandler.applyPreHandle(processedRequest, response)) { //不存在前置处理,就直接返回(后面的post 和completion都不用处理了)
					return;
				}

				try {
					// Actually invoke the handler.
					mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
				}
				finally {
					if (asyncManager.isConcurrentHandlingStarted()) {
						return;
					}
				}

				applyDefaultViewName(request, mv);
                                                                 //后置处理
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
				dispatchException = ex;
			}
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Error err) {
			triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
		}
		finally {
			if (asyncManager.isConcurrentHandlingStarted()) {
				// Instead of postHandle and afterCompletion
				mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				return;
			}
			// Clean up any resources used by a multipart request.
			if (multipartRequestParsed) {
				cleanupMultipart(processedRequest);
			}
		}
	}
//前后置有包含多个过滤器,和处理处理过后的处理triggerAfterCompletion
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (getInterceptors() != null) {
			for (int i = 0; i < getInterceptors().length; i++) {
				HandlerInterceptor interceptor = getInterceptors()[i];
				if (!interceptor.preHandle(request, response, this.handler)) {
					triggerAfterCompletion(request, response, null);
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		return true;
	}

	/**
	 * Apply postHandle methods of registered interceptors.
	 */
	void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
		if (getInterceptors() == null) {
			return;
		}
		for (int i = getInterceptors().length - 1; i >= 0; i--) {
			HandlerInterceptor interceptor = getInterceptors()[i];
			interceptor.postHandle(request, response, this.handler, mv);
		}
	}

	/**
	 * Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
	 * Will just invoke afterCompletion for all interceptors whose preHandle invocation
	 * has successfully completed and returned true.
	 */
	void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)
			throws Exception {

		if (getInterceptors() == null) {
			return;
		}
		for (int i = this.interceptorIndex; i >= 0; i--) {
			HandlerInterceptor interceptor = getInterceptors()[i];
			try {
				interceptor.afterCompletion(request, response, this.handler, ex);
			}
			catch (Throwable ex2) {
				logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
			}
		}
	}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/714236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于credal set和credal decision tree的一点思考(其实就是论文笔记)

阅读Abelln老师的Credal-C4.5时&#xff0c;发现好难。。。然后又额外补充了一些论文&#xff0c;终于稍微懂一点点了&#xff0c;所以记录如下。 credal set在DS theory的定义如下 [1]&#xff1a; 这句话的意思是&#xff08;证据理论中的&#xff09;credal set是一个概率…

Web安全-Behinder(冰蝎)Webshell管理工具使用

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 工具下载地址02 运行环境03 工具介绍04 使用案例 01 工具下载地址 https://github.com/rebeyond/Behinder点击页面右侧"releases"&#xff0c;进入工具的版本下载页面。 在个人终端安…

经典软件工程复兴?大模型驱动的软件工程实践标准化

TL&#xff1b;DR。 简单来说&#xff0c;本文探讨了大模型驱动的软件工程实践标准化&#xff0c;以及如何将需求和设计规范化为 DSL 格式。通过这种方式&#xff0c;可以让 AI 更自动化、高效地编写代码。 随着大语言模型在软件开发中的应用越来越广泛&#xff0c;传统的软件工…

sourcetree中添加秘钥 - 工具篇

文章目录 1. 首先配置秘钥2. 打开sourcetree 1. 首先配置秘钥 参考文章&#xff1a;https://blog.csdn.net/qq_40968685/article/details/131328007 2. 打开sourcetree 打开“选项” 然后&#xff0c;从gitlab中复制ssh地址到sourcetree中&#xff0c;会看到如图提示&…

【python】ndarray的广播功能

目录 0.环境 1.背景简介 2.ndarray的广播功能 2.1概念 2.2意义 2.3使用前提 2.4举例 2.5完整代码 0.环境 windows jupyter notebook验证代码 1.背景简介 我是在查询【ndarray和array的区别】时&#xff0c;看到了“广播功能”这个词&#xff0c;之前只在网络的相关定义…

分布式版本控制系统Git介绍

Git 是一款开源的分布式版本控制系统&#xff0c;具备分布式、轻量级分支、强大的协作能力以及适用于大小项目的版本管理。本文简要介绍Git工具的特性、Git中的对象以及分支管理&#xff0c;以加深了解。 1、版本控制系统介绍 版本控制是指对软件开发过程中各种程序代码、配置…

Docker是什么以及docker的常用命令

Docker简介 Docker是一种开源的容器化平台&#xff0c;用于构建、部署和运行应用程序。它允许开发人员将应用程序及其所有依赖项打包到一个称为"容器"的独立单元中。这个容器可以在任何支持Docker的环境中运行&#xff0c;无论是开发人员的本地机器、虚拟机还是云服务…

Bert

参考资料&#xff1a; 《机器学习》李宏毅 1 Bert 是怎么运作的&#xff1f; Bert 是一种自监督学习&#xff08;Self-supervised Learning&#xff09;模型。Bert 的目标是 pre-train 出一个能够理解语义的多功能语言模型&#xff0c;使之能够在特定任务上只学习较少的带标…

快速上手 vercel,手把手教你白嫖部署上线你的个人项目

壹 ❀ 关于 vercel Vercel 是一个云服务平台&#xff0c;支持静态网站&#xff08;纯静态页面&#xff0c;比如现在base utils 文档也是基于vercel&#xff09;和动态网站的应用部署、预览和上线。如果你用过 GitHub Pages &#xff0c;那么心里可能不会太陌生&#xff0c;但你…

Web3 在Truffle项目中编写出自己的第一个solidity智能合约

好 上文Web3本地搭建truffle智能合约开发环境我们在本地搭起了一个 Truffle 项目 然后 我们说明项目中文件的用途 然后 我们还是通过ganache模拟一个本地的区块链环境 然后打开我们搭建的Truffle项目 首先 我们第一个要看的肯定是truffle-config.js 肯定要先配好连接的环境 我…

UDP 协议【传输层协议】

文章目录 1. 传输层1.1 TCP 与 UDP 2. 端口号2.1 端口号标识进程2.2 通过IP地址、端口号、协议号进行通信识别2.3 协议号2.4 端口号的范围2.5 常用命令netstatiostatpidof 2.6 存疑 3. UDP 协议3.1 地位3.2 报头的分离和交付3.3 UDP 报文的格式3.4 UDP 数据封装和分用数据封装数…

rk3288中apk串口打开失败,selinux权限问题

apk打开串口失败 报错信息&#xff1a; 07-03 17:05:27.030 4582 4582 W jw.ComAssistant: type1400 audit(0.0:56): avc: denied { read } for name"ttyS2" dev"tmpfs" ino7704 scontextu:r:untrusted_app:s0:c512,c768 tcontextu:object_r:ttyS2_dev…

《YOLOv8魔术师》专栏介绍 CSDN独家改进创新实战专栏目录

&#x1f4a1;&#x1f4a1;&#x1f4a1;Yolov8魔术师&#xff0c;独家首发创新&#xff08;原创&#xff09;&#xff0c;持续更新&#xff0c;适用于Yolov5、Yolov7、Yolov8等各个Yolo系列&#xff0c;专栏文章提供每一步步骤和源码&#xff0c;轻松带你上手魔改网络 &…

xml合并

from xml.etree.ElementTree import ElementTree, Element, parseimport xml.etree.ElementTree as ETimport osimport shutilhole_path ./Annotationsarm_path ./Annotations1out_path ./out# 格式化def __indent(elem, level0):i "\n" level*"\t"if…

UE5.2 LyraDemo源码阅读笔记(三)

进入淘汰模式游戏流程 启动游戏&#xff0c;进入流程&#xff1a; 1、进入Lyra游戏第三个体验入口FrontEnd。 2、来到大厅主界面后&#xff0c;点击&#xff1a; Play Lyra > Start A Game >ELIMINATION就会进入到淘汰模式游戏。 看看蓝图和代码&#xff0c;其中的UI流程…

dubbo-admin下载安装教程

目录 1.下载 2.项目结构 3.后端打包 4.前端打包 4.1.node js环境准备 4.2.依赖安装 4.3.启动、打包 1.下载 下载地址&#xff1a; GitHub - apache/dubbo-admin at develop dubbo-admin项目有多个分支&#xff0c;最新版本的dubbo-admin在使用go语言进行重构&#xf…

解决电脑提示vcruntime140_1.dll无法继续执行代码的问题

vcruntime140_1.dll丢失要怎么办&#xff1f;其实很多人都在头疼这个问题&#xff0c;关于dll文件的丢失这事情是时常发生的&#xff0c;因为电脑的杀毒软件有时候会误杀&#xff0c;然后就会导致你的游戏程序都打开不了&#xff0c;你必须要修复好了才行&#xff0c;今天小编就…

统计文本中的数字出现频次

统计文本中的数字出现频次&#xff1a;磁盘上有多个文本文件&#xff0c;统计数据写入excel。 (本笔记适合初通 Python 的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教…

AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘

在使用ddddocr进行图片识别时&#xff0c;报错了&#xff1a; AttributeError: module PIL.Image has no attribute ANTIALIAS 我使用的是Python 3.11&#xff0c;查看一下pillow的版本&#xff1a; print(PIL.__version__)10.0.0 到处百度也没找到原因&#xff0c;最后&am…

IDEA解析Maven依赖过慢

查看Maven配置文件&#xff0c;是否更改为阿里源 maven安装目录/conf/setting.xml 搜索mirrors并在其中添加 <mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/ </url&…