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文章来源:https://www.toymoban.com/news/detail-520550.html
//配合适配器模式,规范了处理流程文章来源地址https://www.toymoban.com/news/detail-520550.html
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);
}
}
}
到了这里,关于4.设计模式之后七种模式后11种模式命令访问者迭代器发布订阅中介者忘备录解释器状态策略职责链和空模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!