1.命令(command)模式 不知道命令接收者(对象)是谁,支持撤销 (接受者 间接调用执行 的具体行为) 命令调用者和接收者解耦
//只要实现命令接口即可 (就是客户端给个命令,然后命令类传给接收类执行)
- 优点和缺点 容易撤销操作 命令队列可以多线程操作
增加过多的命令类
空命令也是一种设计模式,可以减少对象判空
//具体的操作类
//命令模式实现智能家电系统
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)模式
- 原理: 让被访问的类加个对外访问接待的接口,避免不同操作(没有关系)污染访问者类
双分派,第一次参数以类的父类的形式传入方法,第二次用this传入父类的方法
只要加入一个Action就可以不用改其他代码- 优点和缺点 符合单一职责模式, 可做报表 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.迭代器模式(工作用得多) 统一遍历的方式 数组还是集合还是其他(链表…)格式(添加到集合也是聚合组合)
- 先实现Iterator类,然后进行构建不同方式遍历,返回给客户端迭代器对象
- 优点缺点 单一职责原则,但每个类都要一个迭代器不好管理
//迭代器原理
//实现院系和专业的深度遍历原理图
//先创建要迭代的对象
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)模式(行为模式) 避免多对多关系相互调用,使用中介一对多集中同一管理 子系统解耦
- MVC模式 view去调用controller调用多个model/dao处理业务
Mediator调用同事的关系和同事类Coleague管理其他关系和得到Mediotor类- 优点和缺点 类的网状结构转变为星型结构 符合迪米特法则,但中介者出现问题,整个系统受影响
设计不当中介者对象会变得复杂
//中介者模式实现家居管理系统
//中介者
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处理备份) (回退 行为模式)备份原来对象的属性到另外一个对象,原来状态以后可以恢复
- originator(发起人) 有备份方法和(客户端给备忘录对象)回退原来memento数据方法,可以保存多个忘备录对象
- 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.备忘录的注意事项
- 用户不需要关心保存的细节,但类成员变量太多每次保存需要耗费内存
- 应用场景 后悔药 ctrl+z 打游戏时的存档,ie的回退 数据库的事务管理
- 和原型模式(对象的浅拷贝和深拷贝)配合使用,可以节省内存
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的使用
是抽象表达式SpelExpression和LiteralExpression是实现的解析表达式的类
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因为更改需要不停变化) 图
- 优缺点 对象不需要找到链结构,但是链可能过长影响性能,需要设置阈值,setNext()判断是否超出,以防退化为链表
- 应用场景 多个对象处理同个请求 多级请求.请假/加薪等审批流程 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);
}
}
}