目录
状态(State)模式
适用场景
UML图
示例代码
优缺点
状态模式VS策略模式
实例:一天中的工作状态
应用:工作中的请假流程
本质:根据状态来分离和选择行为。状态驱动,由上下文负责
当一个对象状态转换的条件表达式过于复杂时,把状态的转换逻辑移到表示不同状态的一系列类中,把复杂的逻辑简化。
当某一事物在不同的状态下有不同表现(动作),而一个状态又会在不同表现下转移到下一个不同状态时,使用大量的Switch–Case语句是不可取的。
状态模式应运而生,将依赖于对象状态的分支封装到独立的类中。它允许一个对象在其内部状态改变时改变它的行为,看起来对象似乎修改了它的类(但实际上是从一个类跳转到另一个类)
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{
@Override
public void Handle(Context context) {
context.setState(new ConcreteStateB());
//传给B状态
}
}
public class ConcreteStateB extends State{
@Override
public 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状态
优点:
缺点:
策略模式:定义了算法家族,分别封装起来,让他们之间可以相互转换
状态模式:当一个状态的内部状态改变时允许改变其行为,这个对象看起来改变了其类
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{
@Override
public 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{
@Override
public 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{
@Override
public 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{
@Override
public void play(Work w) {
System.out.println(w.getHour()+":工作完成了,睡觉");
}
}
public class WorkedState extends State{
@Override
public void play(Work w) {
System.out.println(w.getHour()+":工作还没有完成,加班");
}
}
public class SleepState extends State{
@Override
public 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{
@Override
public void play(Apply a) {
if(a.isOk1()) {
a.setState(new TimeState());
a.play();
}else {
System.out.println("你的请假未被项目经理通过");
}
}
}
public class TimeState extends State{
@Override
public void play(Apply a) {
if(a.getTime()<=3) {
System.out.println("你的请假已被项目经理通过");
}else {
a.setState(new DmanagerState());
a.play();
}
}
}
//部门经理
public class DmanagerState extends State{
@Override
public 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();
}
}