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

news/2024/4/29 16:35:03/文章来源:https://blog.csdn.net/weixin_47039303/article/details/131491974

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;}@Overridepublic void execute() {light.off();}@Overridepublic void undo() {light.on();}
}
public class LightOnCommand implements Command {Light light;LightOnCommand(Light light){super();this.light=light;}@Overridepublic void execute() {light.on();}@Overridepublic void undo() {light.off();}
}
//也是一种命令模式,用于初始化
public class NoCommand implements Command {@Overridepublic void execute() {}@Overridepublic 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{@Overridepublic void getWomanResult(WoMan woMan) {System.out.println("女人"+ woMan.name+"评价差评");}@Overridepublic void getManResult(Man men) {System.out.println("男人"+ men.name+"评价差评");}
}
public class NoGood extends Action{@Overridepublic void getWomanResult(WoMan woMan) {System.out.println("女人"+ woMan.name+"评价待定");}@Overridepublic void getManResult(Man men) {System.out.println("男人"+ men.name+"评价待定");}
}
public class Sucess extends Action{@Overridepublic void getWomanResult(WoMan woMan) {System.out.println("女人"+woMan.getName()+"评价点赞");}@Overridepublic 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;@Overridevoid 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;@Overridevoid 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>() {@Overridepublic 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(){}@Overridepublic 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(){}@Overridepublic 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;}@Overridepublic boolean hasNext() {if(index+1 > length||departments[index+1]==null){return false;}return true;}@Overridepublic 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;}@Overridepublic boolean hasNext() {if(index+1 >= infoList.size()){return false;}return true;}@Overridepublic 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<>();@Overridepublic void registerUser(Observer observer) {list.add(observer);}@Overridepublic void removeUser(Observer observer) {list.remove(observer);}@Overridepublic void notifyUser() {for (int i=0;i<list.size();i++){list.get(i).update(this);}}@Overridepublic 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{@Overridepublic void update(WeatherData weatherData) {System.out.println("百度调用 今天温度:"+weatherData.centigrade+"湿度:"+weatherData.humidity);}
}
public class XinlangWeatherObserver implements Observer{@Overridepublic 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>();@OverrideString getMessage(String name) {String str="中介得到信息"+name;System.out.println(str);return str;
//        Colleage colleage=(Colleage)(map.get(str));
//        if(colleage instanceof ){
//
//
//        }}@OverrideString sendMessageToTV(String str) {System.out.println("中介接收到消息"+str);Tv tv=(Tv)(map.get("电视"));tv.sendStatueToTV(str);return null;}@Overridevoid registerColleague(String name,Colleague colleague) {map.put(name,colleague);}@Overridevoid 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;}@Overridevoid sendStatue() {System.out.println("电视发送消息成功");String msg = mediator.getMessage("法外狂徒张三");}@Overridevoid sendStatueToTV() {}@Overridevoid sendStatueToTV(String str) {System.out.println("tv接收到消息:"+str);}
}
public class Projector extends Colleague {Mediator mediator;Projector(Mediator mediator){this.mediator=mediator;}@Overridevoid sendStatue() {System.out.println("投影仪发送消息成功");String msg = mediator.getMessage("法外狂徒张三");}@Overridevoid sendStatueToTV() {System.out.println("投影仪向tv发出信息");mediator.sendMessageToTV("你好tv我是projector");}@Overridevoid 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=cpublic VarExpression(String key) {this.key = key;}// var 就是{a=10, b=20}// interpreter 根据 变量名称,返回对应值@Overridepublic 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 是一个默认实现@Overridepublic int interpreter(HashMap<String, Integer> var) {// TODO Auto-generated method stubreturn 0;}
}public class AddExpression extends SymbolExpression  {public AddExpression(Expression left, Expression right) {super(left, right);}//处理相加//var 仍然是 {a=10,b=20}..//一会我们debug 源码,就okpublic int interpreter(HashMap<String, Integer> var) {//super.left.interpreter(var) : 返回 left 表达式对应的值 a = 10//super.right.interpreter(var): 返回right 表达式对应值 b = 20return 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加入stackbreak;case '-': // left = stack.pop();right = new VarExpression(String.valueOf(charArray[++i]));stack.push(new SubExpression(left, right));break;default: //如果是一个 Var 就创建要给 VarExpression 对象,并push到 stackstack.push(new VarExpression(String.valueOf(charArray[i])));break;}}//当遍历完整个 charArray 数组后,stack 就得到最后Expressionthis.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 stubString expStr = getExpStr(); // a+bHashMap<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币");}@Overridepublic 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;}@Overridepublic 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));}}//开始抽奖@Overridepublic 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));}}}@Overridepublic void starting() {System.out.println("请先抽奖");}@Overridepublic void givePrice() {System.out.println("请先抽奖");}}//抽到奖品
public class RafflePrizeState extends State {Context context;RafflePrizeState(Context context){this.context=context;}@Overridepublic void dispenseQB() {context.setState(new InitState(context));context.getState().dispenseQB();}@Overridepublic void start() {context.setState(new InitState(context));context.getState().start();}@Overridepublic void starting() {context.setState(new InitState(context));context.getState().starting();}@Overridepublic void givePrice() {context.setState(new InitState(context));context.getState().givePrice();}}//没有抽到奖品
public class RaffleNoPrizeState extends State {Context context;RaffleNoPrizeState(Context context) {this.context = context;}@Overridepublic void dispenseQB() {context.setState(new InitState(context));}@Overridepublic void start() {context.setState(new InitState(context));}@Overridepublic void starting() {context.setState(new InitState(context));}@Overridepublic void givePrice() {context.setState(new InitState(context));}
}//抽到奖品
public class RafflePrizeState extends State {Context context;RafflePrizeState(Context context){this.context=context;}@Overridepublic void dispenseQB() {context.setState(new InitState(context));context.getState().dispenseQB();}@Overridepublic void start() {context.setState(new InitState(context));context.getState().start();}@Overridepublic void starting() {context.setState(new InitState(context));context.getState().starting();}@Overridepublic 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{@Overridepublic void attack() {System.out.println("可以近战攻击");}public void discard(){System.out.println("不可丢弃");}
}
//投掷物攻击
public class FlingAttack implements Weapon{@Overridepublic void attack() {System.out.println("可以投掷");}@Overridepublic void discard() {System.out.println("按G不可丢弃,只可投掷");}
}
//远程攻击
public class RemoteAttack implements Weapon{@Overridepublic void attack() {System.out.println("可以远程发射子弹");}@Overridepublic void discard() {System.out.println("可以丢弃");}
}

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

public interface RoleAction {public void CanRiseUPFoot();
}
//飞虎队不可以踢腿
public class FHDRoleAction implements RoleAction {@Overridepublic void CanRiseUPFoot() {System.out.println("飞虎队不可以踢腿");}
}//审判者可以踢腿
public class JudgerRoleAction implements RoleAction {@Overridepublic 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>() {@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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 afterCompletionmappedHandler.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.luyixian.cn/news_show_325629.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

揭秘元宇宙背后的最炫科技风

&#xff1a;元宇宙&#xff0c;这个词汇在近年来越来越被人们所熟知。它是一个虚拟的世界&#xff0c;由数字化的现实世界和虚拟现实技术所构成。在元宇宙中&#xff0c;人们可以自由地探索、交互、创造和享受各种虚拟体验。而这一切&#xff0c;都离不开最炫科技风的支持。 …

道路车辆功能安全第2 部分:功能安全管理

道路车辆功能安全 第2 部分&#xff1a;功能安全管理 1 范围 GB/T 34590的本部分规定了应用于汽车领域的功能安全管理的要求&#xff0c;包括&#xff1a; ——独立于项目的关于所涉及组织的要求&#xff08;整体安全管理&#xff09;&#xff1b;及 ——项目特定的在安全生命周…

Docker常见问题集合

一、Docker安装 1、yum 安装 1&#xff09;更新yum包到最新 yum update2&#xff09;安装软件需要的软件&#xff0c;yum-util&#xff08;提供 yum-config-manager 功能&#xff09;&#xff0c;device-mapper-persistent-data、lvm2&#xff08;devicemapper 驱动依赖&…

【Linux】Redis 集群部署

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Redis 集群部署 Redis 主从复制主从复制的作用主从复制的流程搭建Redis 主从复制安装 Redis修改 Redis 配置文件&#xff08;Master节点操作&#xff09;修改 Redis 配置文件…

STM32——建工程

文章目录 一、建工程步骤1. 创建一个工程文件2. 里面创建四个文件3. Lib&#xff1a;存放标准库的.c和.h文件&#xff0c;其中inc放置.h文件&#xff0c;src放置.c文件4. Startup中存放驱动文件5.User文件中包含以下路径以下文件6.创建工程Project 一、建工程步骤 以STM32F10X…

百万连接实现01:使用epoll+多线程+多IP地址管理tcp客户端集群

操作系统采用 <客户端IP : 客户端端口> : <服务端IP : 服务端端口> 四元组来标识一条TCP连接。 所以要想实现百万连接&#xff1a; 第一种是服务器端只开启一个进程&#xff0c;然后使用很多个客户端进程绑定不同的客户端 ip 来连接&#xff0c;假设 20个ip * 5w&a…

AIGC - Easy Diffusion (Stable Diffusion) 图像生成工具的环境配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131524075 版本v2.5.41 Stable Diffusion 图像生成工具是一种基于深度学习的技术&#xff0c;可以从随机噪声中生成高质量的图像&#x…

计模式篇(Java):桥接模式

上一篇&#xff1a;计模式篇(Java)&#xff1a;适配器模式 九、桥接模式 需求示例 当我们对不同手机类型的不同品牌实现操作编程&#xff0c;如图&#xff1a; 那么它对应的类图就是 传统方式解决需求分析&#xff1a; 扩展性问题&#xff0c;如果需要在增加手机的样式&#x…

自学网络安全究竟该从何学起?

一、为什么选择网络安全&#xff1f; 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地&#xff0c;网络安全行业地位、薪资随之水涨船高。 未来3-5年&#xff0c;是安全行业的黄金发展期&#xff0c;提前踏入行…

MATLAB | 拉普拉斯分布/拉普拉斯噪声的生成

一、实验目标 生成拉普拉斯分布的噪声&#xff0c;并分析它的概率密度函数 二、解决思路 &#xff08;1&#xff09;拉普拉斯分布可以由指数分布生成 拉普拉斯的概率密度函数为 f ( x ; μ , λ ) 1 2 λ e − ∣ x − μ ∣ λ f(x;\mu,\lambda)\frac{1}{2 \lambda} e^{…

简单的手机记事本怎么把英文翻译成中文?

手机记事本是人们常用的辅助工具之一&#xff0c;在使用手机记事本记录内容的时候&#xff0c;除了我们平时使用较多的中文之外&#xff0c;也有人会记录一些英文内容。想要将手机记事本中的英文内容翻译成中文内容应该如何操作呢&#xff1f;以iPhone手机端敬业签记事本软件为…

GIS杂记(二):Arcgis对采样点进行裁剪,获取指定区域内的采样点

有时候需要对栅格数据进行采样处理&#xff0c;如果采样点过多则会使得采样时间过长&#xff0c;今天在进行数据采样时&#xff0c;使用了1km*1km的渔网建立的采样点&#xff0c;大概有1百万个点&#xff0c;程序运行时间大概4个小时&#xff0c;但是其中有绝大部分数据都是空值…

Css 基础:选择器,三大特性

1.emmet的 快速格式化代码 配置 "editor.formatOnType": true, "editor.formatOnSave": true 2.基础选择器 3.复合选择器 4.单行文本垂直居中原理 5.css背景 6.CSS三大特性 层叠性&#xff1a;相同选择器设置相同样式&#xff0c;发生在样式冲突时&#xf…

【PC】CPU与GPU

文章目录 CPU与主板CPU是什么主板是什么功能 GPU与显卡GPU是什么显卡是什么功能 CPU与GPU的关系 ALU&#xff1a; 算术单元&#xff08;Arithmetic Unit&#xff09;&#xff1a;算术单元执行基本的算术运算&#xff0c;如加法、减法、乘法和除法。它能够对整数、浮点数和定点数…

Web服务器群集:LVS+Keepalived高可用群集

目录 一、理论 1.Keepalived 2.VRRP协议&#xff08;虚拟路由冗余协议&#xff09; 3.部署LVSKeepalived 高可用群集 二、实验 1.LVSKeepalived 高可用群集 三、问题 1.备服务器网卡启动报错 四、总结 一、理论 1.Keepalived &#xff08;1&#xff09;简介 Keepal…

Redis高可用群集---搭建(主从、哨兵、Cluster)

目录 Redis 高可用集群Redis 主从复制Redis 哨兵模式Redis 集群模式 Redis 高可用集群 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redi…

MySQL原理探索——22 MySQL有哪些“饮鸩止渴”提高性能的方法

不知道你在实际运维过程中有没有碰到这样的情景&#xff1a;业务高峰期&#xff0c;生产环境的 MySQL 压力太大&#xff0c;没法正常响应&#xff0c;需要短期内、临时性地提升一些性能。 我做项目的时候&#xff0c;就偶尔会碰上这种场景。用户的开发负责人说&#xff0c;不管…

Spring中bean使用方法

Spring框架是一个非常重要的开发工具&#xff0c;它提供了丰富的功能和模块&#xff0c;其中核心的概念之一就是Spring Bean。Spring Bean是Spring IoC容器中的一个对象&#xff0c;它负责管理一个Java对象的生命周期以及依赖注入。下面我将通过互联网场景下的相关背景内容来阐…

4通道AD采集子卡模块有哪些推荐?

FMC134是一款4通道3.2GSPS&#xff08;2通道6.4GSPS&#xff09;采样率12位AD采集FMC子卡模块&#xff0c;该板卡为FMC标准&#xff0c;符合VITA57.4规范&#xff0c;可以作为一个理想的IO模块耦合至FPGA前端&#xff0c;16通道的JESD204B接口通过FMC连接器连接至FPGA的高速串行…

分布式系统监控zabbix安装部署及自定义监控

系列文章目录 文章目录 系列文章目录一、zabbix1.zabbix的基本概述2.zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。3.zabbix 监控原理4.Zabbix 6.0 功能组件5. zabbix的监控对象6.zabbix的常用术语7.zabbix进程详解8.zabbix的监控框…