状态模式:用官方的话来说就是,当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。说白了这个模式就是为了消除庞大的分支语句。
使用场景:
官方话来说就是,当一个对象的行为取决于他的状态,并且他在运行的时刻根据状态改变他的行为时使用,其实就是出现特别复杂庞大的分支语句的时候,或者因为这些分之语句导致耦合性特别高的时候使用。
优点:
将与特定状态相关的的行为局部化,并且将不同的状态的行为分割开来。
UML图:
实现代码
package com.liran.main.DesignPattern.状态模式;
/**
* 状态模式
* Created by LiRan on 2016-02-22.
*/
public class StatePattern {
public static void main(String[] args) {
Context context = new Context(new ConcreteStateA());
//切换状态
context.requst();
context.requst();
context.requst();
}
}
abstract class State {
public abstract void Handle(Context context);
}
class ConcreteStateA extends State {
@Override
public void Handle(Context context) {
context.setState(new ConcreteStateB());
}
@Override
public String toString() {
return "ConcreteStateA";
}
}
class ConcreteStateB extends State {
@Override
public void Handle(Context context) {
context.setState(new ConcreteStateA());
}
@Override
public String toString() {
return "ConcreteStateB";
}
}
class Context {
private State state;
public Context(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
System.out.println("现在的状态是:" + state.toString());
}
public void requst() {
state.Handle(this);
}
}
华丽的分割线
还是不太懂:
我知道,上面的东西有点抽象,这个模式我也是第一遍没看懂,后来做了一个实例,然后就明白了,这样来吧,咱们假设一个情景:程序员加班都是家常便饭,但是有些时候的加班是因为没有完成工作任务而加班的,不仅没有加班费,当项目紧的时候有可能一个月都在加班,这样效率很不好,早上应该还能精神百倍的写代码,但是中午吃饭的时候就会犯困,要等到下午才能恢复工作的经理,到了下班的时间如果没有完成那就要加班,如果已经完成了,那就可以下班回家睡觉了,如果加班太晚的话,那就会在公司睡着了,就是这么一个情景,如果按照以前的写法,肯定又是一堆的判断语句,这样很不好,比如突然要增加下午茶时间,那个时间都不敲代码,这个东西改起来就比较麻烦,而且容易出错,并且也不够清晰,代码会显得逻辑很乱,如果采用状态模式
,那我们就可以把每一个判断分之都弄成一种类,然后有一个抽象的状态类,来一个工作类进行调度,具体代码如下:
实例代码二:
package com.liran.main.DesignPattern.状态模式;
/**
* 演示例子
* Created by LiRan on 2016-02-22.
*/
public class StatePattern_example {
public static void main(String[] args) {
Work work = new Work();
work.hour = 9;
work.writeProgram();
work.hour = 11;
work.writeProgram();
work.hour = 12;
work.writeProgram();
work.hour = 15;
work.writeProgram();
work.isFinish=true;
work.hour = 19;
work.writeProgram();
work.hour = 21;
work.writeProgram();
work.hour = 22;
work.writeProgram();
work.hour = 23;
work.writeProgram();
}
}
class Work {
public int hour;
public boolean isFinish;
private WorkState current;
public Work() {
current = new MorinigState();
}
public WorkState getState() {
return current;
}
public void setState(WorkState current) {
this.current = current;
}
public void writeProgram() {
current.writeProgram(this);
}
}
/**
* 抽象工作状态类
*/
abstract class WorkState {
abstract public void writeProgram(Work w);
}
/**
* 上午工作状态
*/
class MorinigState extends WorkState {
@Override
public void writeProgram(Work w) {
if (w.hour < 12) {
System.out.println("当前时间是:" + w.hour + " 精神百倍");
} else {
w.setState(new noonState());
w.writeProgram();
}
}
}
/**
* 中午工作状态
*/
class noonState extends WorkState {
@Override
public void writeProgram(Work w) {
if (w.hour < 13) {
System.out.println("当前时间是:" + w.hour + " 吃午饭 困 午休 ");
} else {
w.setState(new afternoonState());
w.writeProgram();
}
}
}
/**
* 下午工作状态
*/
class afternoonState extends WorkState {
@Override
public void writeProgram(Work w) {
if (w.hour < 17) {
System.out.println("当前时间是:" + w.hour + " 感觉状态还不错 ");
} else {
w.setState(new eveningState());
w.writeProgram();
}
}
}
/**
* 晚上工作状态
*/
class eveningState extends WorkState {
@Override
public void writeProgram(Work w) {
if (w.isFinish) {
w.setState(new restState());
w.writeProgram();
} else {
if (w.hour < 21) {
System.out.println("当前时间是:" + w.hour + " 加班啊 ");
} else {
w.setState(new SleepingState());
w.writeProgram();
}
}
}
}
class SleepingState extends WorkState {
@Override
public void writeProgram(Work w) {
System.out.println("当前时间是:" + w.hour + " 不行了 睡着了 ");
}
}
class restState extends WorkState {
@Override
public void writeProgram(Work w) {
System.out.println("当前时间是:" + w.hour + " 下班回家了 ");
}
}
运行结果:
工作完成的话:
当前时间是:9 精神百倍
当前时间是:11 精神百倍
当前时间是:12 吃午饭 困 午休
当前时间是:15 感觉状态还不错
当前时间是:19 下班回家了
当前时间是:21 下班回家了
当前时间是:22 下班回家了
当前时间是:23 下班回家了
不能完成的话:
当前时间是:9 精神百倍
当前时间是:11 精神百倍
当前时间是:12 吃午饭 困 午休
当前时间是:15 感觉状态还不错
当前时间是:19 加班啊
当前时间是:21 不行了 睡着了
当前时间是:22 不行了 睡着了
当前时间是:23 不行了 睡着了
源码下载:Github
有什么疑问的地方欢迎评论。