状态模式的应用场景
在我们开发过程中经常会遇到根据某个状态不同,执行不同的链路。以至于很有可能写出那种飞机翅膀那种if else
代码。例如下面:
package com.demo.test.state;
public class Demo {
//当前时间时间
private int currTime = 8;
//1:未起床,2:起床了,3:吃完饭了。4:工作签到
private int state = 1;
public Demo(int cTime,int s){
currTime = cTime;
state = s;
}
public void main(){
//当时间8点之前,还没有起床。那么就要迟到了。
if(currTime <= 8 ){
if(state == 1){
System.out.println("哇!又迟到了");
}else if(state == 2){
System.out.println("来不及吃饭了,我要赶紧上班了");
}else if(state == 3){
System.out.println("睡好吃足,状态满满上班去");
}else if(state == 4){
System.out.println("上班那么早,生产队的驴都没你这么辛苦。");
}else{
System.out.println("未知状态,错误警告");
}
}else if(currTime == 9 ){
if(state == 1){
System.out.println("完蛋,今天要旷工了");
}else if(state == 2){
System.out.println("哇!来不及吃饭了,马上要迟到了");
}else if(state == 3){
System.out.println("抓紧抓紧,马上要迟到了");
}else if(state == 4){
System.out.println("coding。。。。请勿打扰");
}
}else{
if(state == 4){
System.out.println("ding。。。迟到打卡。奖励-100元。");
}else{
System.out.println("旷工旷工旷工!!!");
}
}
}
}
客户端
package com.demo.test.state;
public class Client {
public static void main(String[] arg){
Demo demo = new Demo(10,4);
demo.main();
}
}
这样的代码维护起来成本高,而且还很容易出错。仅这样逻辑简单的代码,就有这样一大篇,放到业务那维护的起来更是难上加难。
状态模式的代码
抽象状态
package com.demo.test.state.mode.iml;
import com.demo.test.state.mode.WorkContext;
public interface State {
public abstract void handle(WorkContext w);
}
当前时间8点下状态表现的具体类
package com.demo.test.state.mode;
import com.demo.test.state.mode.iml.State;
public class CurrTime8 implements State {
@Override
public void handle(WorkContext workContext) {
if(workContext.getCurrTime() <= 8){
delay(workContext);
}else{
workContext.setState(new CurrTime9());
workContext.work();
}
}
private void delay(WorkContext workContext){
if(workContext.getPersonState() == 1){
System.out.println("哇!又迟到了");
}else {
notEat(workContext);
}
}
private void notEat(WorkContext workContext){
if(workContext.getPersonState() == 2){
System.out.println("来不及吃饭了,我要赶紧上班了");
}else {
eat(workContext);
}
}
private void eat(WorkContext workContext){
if(workContext.getPersonState() == 3){
System.out.println("睡好吃足,状态满满上班去");
}else{
working(workContext);
}
}
private void working(WorkContext workContext){
if(workContext.getPersonState() == 4){
System.out.println("上班那么早,生产队的驴都没你这么辛苦。");
}else{
other();
}
}
private void other(){
System.out.println("未知状态,错误警告");
}
}
当前时间9点下状态表现的具体类
package com.demo.test.state.mode;
import com.demo.test.state.mode.iml.State;
public class CurrTime9 implements State {
public void handle(WorkContext workContext){
if(workContext.getCurrTime() == 9 ){
this.absenteeism(workContext);
}else{
workContext.setState(new CurrTime10());
workContext.work();
}
}
private void absenteeism(WorkContext workContext){
if(workContext.getPersonState() == 1){
System.out.println("完蛋,今天要旷工了");
}else{
delay(workContext);
}
}
private void delay(WorkContext workContext){
if(workContext.getPersonState() == 2){
System.out.println("哇!来不及吃饭了,马上要迟到了");
}else{
maybeDelay(workContext);
}
}
private void maybeDelay(WorkContext workContext){
if(workContext.getPersonState() == 3){
System.out.println("抓紧抓紧,马上要迟到了");
}else {
working(workContext);
}
}
private void working(WorkContext workContext){
if(workContext.getPersonState() == 4){
System.out.println("coding。。。。请勿打扰");
}else{
other();
}
}
private void other(){
System.out.println("未知状态,错误警告");
}
}
当前时间10点下状态表现的具体类
package com.demo.test.state.mode;
import com.demo.test.state.mode.iml.State;
public class CurrTime10 implements State {
public void handle(WorkContext workContext){
if(workContext.getCurrTime() >= 10 ){
delay(workContext);
}else{
System.out.println("神奇时间。。。。");
}
}
private void delay(WorkContext workContext){
if(workContext.getPersonState() == 4){
System.out.println("ding。。。迟到打卡。奖励-100元。");
}else{
other();
}
}
private void other(){
System.out.println("旷工旷工旷工!!!");
}
}
客户端
package com.demo.test.state;
import com.demo.test.state.mode.WorkContext;
public class Client {
public static void main(String[] arg){
WorkContext workContext = new WorkContext();
workContext.setCurrTime(8);
workContext.setPersonState(1);
workContext.work();
}
}
总结
状态模式是对不同状态下所作出的不同反应,在未使用状态模式下,想添加一种新状态,就要增加if else
的判断,代码都耦合在一块,极容易因修改而造成错误。
在状态模式下,每个类和方法职业清晰,切容易扩展符合设计模式中的开闭原则。