23种设计模式——状态模式

目录

状态(State)模式

适用场景

UML图

示例代码

优缺点

状态模式VS策略模式

实例:一天中的工作状态

应用:工作中的请假流程


状态(State)模式

本质:根据状态来分离和选择行为。状态驱动,由上下文负责

适用场景

当一个对象状态转换的条件表达式过于复杂时,把状态的转换逻辑移到表示不同状态的一系列类中,把复杂的逻辑简化。

当某一事物在不同的状态下有不同表现(动作),而一个状态又会在不同表现下转移到下一个不同状态时,使用大量的Switch–Case语句是不可取的。

状态模式应运而生,将依赖于对象状态的分支封装到独立的类中。它允许一个对象在其内部状态改变时改变它的行为,看起来对象似乎修改了它的类(但实际上是从一个类跳转到另一个类)

UML图

Context:拥有State的一个引用

State:依赖于Context

示例代码

一个接口或抽象类,封装与Context特定状态相关的行为

public abstract class State {public abstract void Handle(Context context); }

 Context类以及它的一个特定状态:拥有State类的一个对象(引用)

public class Context {private State state;public Context(State state) {super();this.state = state;}public State getState() {return state;}public void setState(State state) {this.state = state;System.out.println(state.getClass().getName());}public void request() {state.Handle(this);//核心}}

具体状态: 每个子类实现与Context的特定状态相关的一个行为 

public class ConcreteStateA extends State{@Overridepublic void Handle(Context context) {context.setState(new ConcreteStateB());//传给B状态}
}
public class ConcreteStateB extends State{@Overridepublic void Handle(Context context) {context.setState(new ConcreteStateA());//传给A状态}}
public class Main {public static void main(String[] args) {Context c=new Context(new ConcreteStateA());c.request();c.request();c.request();}}

第一个c.request():起初Context类中的this是ConcreteStateA,经过request中的Handle(this)传入ConcreteStateA的的Handle(),此处改变为ConcreteStateB

第二个c.request():是从B状态又变为A状态

优缺点

优点:

  • 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来
  • 消除条件分支语句,把状态转移逻辑分布到State的子类,减少了相互间的依赖。
  • 显式化进行状态转换:为不同的状态引入独立的对象,使得状态的转换变得更加明确。而且状态对象可以保证上下文不会发生内部状态不一致的状况,因为上下文中只有一个变量来记录状态对象,只要为这一个变量赋值就可以了

缺点:

  • 逻辑分散化:状态逻辑分布到了State的很多子类中,很难看到整个状态逻辑,这也带来了代码的维护问题


状态模式VS策略模式

在这里插入图片描述

策略模式:定义了算法家族,分别封装起来,让他们之间可以相互转换

状态模式:当一个状态的内部状态改变时允许改变其行为,这个对象看起来改变了其类

  • 相似:都有Context类,都是给一个具有多个子类的父类实现Context的算法逻辑
  • 区别:从二者的UML图可以看出,状态模式中子类ContextState的函数中持有context,通过context可以调用Context中的方法。

实例:一天中的工作状态

public abstract class State {public abstract void play(Work w);
}
public class Work {private int hour;//时间private State state;//状态public static boolean finish;//工作完成标志public Work() {state=new MoringState();}public void play() {state.play(this);//核心}public State getState() {return state;}public void setState(State state) {this.state = state;}public int getHour() {return hour;}public void setHour(int hour) {this.hour = hour;}}
public class MoringState extends State{@Overridepublic void play(Work w) {if(w.getHour()<12)System.out.println(w.getHour()+":上午工作,精神百倍");else {w.setState(new AfternoonState());w.play();}}
}public class AfternoonState extends State{@Overridepublic void play(Work w) {if(w.getHour()<18)System.out.println(w.getHour()+":下午工作,精神还行");else {w.setState(new EveningState());w.play();}}}public class EveningState extends State{@Overridepublic void play(Work w) {if(Work.finish) {w.setState(new RestState());w.play();}else if(w.getHour()>=22) {w.setState(new SleepState());w.play();}else{w.setState(new WorkedState());w.play();}}
}public class RestState extends State{@Overridepublic void play(Work w) {System.out.println(w.getHour()+":工作完成了,睡觉");}
}public class WorkedState extends State{@Overridepublic void play(Work w) {System.out.println(w.getHour()+":工作还没有完成,加班");}
}public class SleepState extends State{@Overridepublic void play(Work w) {System.out.println(w.getHour()+":很晚了,睡觉");}
}
package com.day;public class Main {public static void main(String[] args) {Work w1=new Work();	w1.setHour(15);w1.play();w1.setHour(21);w1.play();//w1.setHour(23);//w1.play();//若仍用w1.setHour(设置的时间点<=之前状态的时间),得到的也还是之前的状态System.out.println("第二天:");Work w2=new Work();w2.finish=true;w2.setHour(20);w2.play();}
}

应用:工作中的请假流程

某人提出请假申请,先由项目经理审批,如果项目经理不同意,审批就直接结束
如项目经理同意,再看是否超过3天,如果三天以内,审批直接结束
否则,交给部门经理,部门经理审核后,无论是否同意,审批直接结束

public abstract class State {public abstract void play(Apply a);
}
package com.apply;public class Apply {private boolean ok1=false;private boolean ok2=false;private int time=0;State state=null;public Apply() {state=new XmanagerState();//项目经理}public void play() {state.play(this);}public boolean isOk1() {return ok1;}public void setOk1(boolean ok1) {this.ok1 = ok1;}public boolean isOk2() {return ok2;}public void setOk2(boolean ok2) {this.ok2 = ok2;}public int getTime() {return time;}public void setTime(int time) {this.time = time;}public State getState() {return state;}public void setState(State state) {this.state = state;}}
//项目经理
public class XmanagerState extends State{@Overridepublic void play(Apply a) {if(a.isOk1()) {a.setState(new TimeState());a.play();}else {System.out.println("你的请假未被项目经理通过");}}
}public class TimeState extends State{@Overridepublic void play(Apply a) {if(a.getTime()<=3) {System.out.println("你的请假已被项目经理通过");}else {a.setState(new DmanagerState());a.play();}}
}//部门经理
public class DmanagerState extends State{@Overridepublic void play(Apply a) {if(a.isOk2()) {System.out.println("你的请假已被部门经理通过");}else {System.out.println("你的请假未被部门经理通过");}}
}
public class Main {public static void main(String[] args) {Apply a1=new Apply();a1.setOk1(true);a1.setTime(5);a1.setOk2(false);a1.play();}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部