状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象像是改变了其类。
乍一看状态模式的解释可能有点不知所以然,其实这个模式并不难理解,首先我们看一个例子
我们定义了一个学习类,它的一个studyStatus()方法采用if-else来做具体的操作。
public class Study { private int studyHours; public int getStudyHours() { return studyHours; } public void setStudyHours(int studyHours) { this.studyHours = studyHours; } public void studyStatus(){ if(studyHours >0 && studyHours<2){ System.out.println("学习时间:"+studyHours+",刚开始学习,精力充沛!"); }else if(studyHours>=2 && studyHours<4){ System.out.println("学习时间:"+studyHours+",稍有疲惫"); }else if(studyHours >=4 && studyHours<5){ System.out.println("学习时间:"+studyHours+",学习效率下降"); }else if(studyHours >=5 && studyHours <7){ System.out.println("学习时间:"+studyHours+",学习效率低下"); }else { System.out.println("学习时间:"+studyHours+",疲惫不堪"); } } }
public class Test { public static void main(String[] args) { Study study = new Study(); study.setStudyHours(1); study.studyStatus(); study.setStudyHours(3); study.studyStatus(); study.setStudyHours(4); study.studyStatus(); study.setStudyHours(6); study.studyStatus(); study.setStudyHours(8); study.studyStatus(); } }
测试结果:
学习时间:1,刚开始学习,精力充沛!
学习时间:3,稍有疲惫
学习时间:4,学习效率下降
学习时间:6,学习效率低下
学习时间:8,疲惫不堪
我们假设StudyStatus的study方法内条件分支有很多(虽然我这里只有5种),当我们把所有分支条件写在一个的方法里时,此时就违反了了“单一职责原则”,除此之外当我们需要修改某一个分支时,这个方法下的其他分支也有可能受到影响,这就违反了“开放-封闭原则”,所以我们做如下改动,首先定义一个状态的接口,实现类中有一方法studyStatus(),当满足条件是执行操作,否则跳入下一分支。
public interface Status { void studyStatus(Study study); } //分支1 public class Status1 implements Status { @Override public void studyStatus(Study study) { int studyHours = study.getStudyHours(); if(studyHours >0 && studyHours < 2){ System.out.println("学习时间:"+studyHours+",刚开始学习,精力充沛!"); }else { study.SetStatus(new Status2()); study.studyStatus(); } } } //分支2 public class Status2 implements Status { @Override public void studyStatus(Study study) { int studyHours = study.getStudyHours(); if(studyHours >=2 && studyHours < 4){ System.out.println("学习时间:"+studyHours+",稍有疲惫"); }else { study.SetStatus(new Status3()); study.studyStatus(); } } } //分支3 public class Status3 implements Status { @Override public void studyStatus(Study study) { int studyHours = study.getStudyHours(); if(studyHours >=4 && studyHours < 5){ System.out.println("学习时间:"+studyHours+",学习效率下降"); }else { study.SetStatus(new Status4()); study.studyStatus(); } } } //分支4 public class Status4 implements Status { @Override public void studyStatus(Study study) { int studyHours = study.getStudyHours(); if(studyHours >=5 && studyHours < 7){ System.out.println("学习时间:"+studyHours+",学习效率低下"); }else { study.SetStatus(new Status5()); study.studyStatus(); } } } //分支5 public class Status5 implements Status { @Override public void studyStatus(Study study) { int studyHours = study.getStudyHours(); System.out.println("学习时间:"+studyHours+",疲惫不堪"); } }
去除if-else判断的学习类,
public class Study { //当前状态 private Status current; private int studyHours; //初始化时从第一个分支开始 public Study(){ this.current = new Status1(); } public void SetStatus(Status status){ this.current = status; } public int getStudyHours() { return studyHours; } public void setStudyHours(int studyHours) { this.studyHours = studyHours; } //获取当前状态 public void studyStatus(){ current.studyStatus(this); } }
测试类
public class Test { public static void main(String[] args) { Study study = new Study(); study.setStudyHours(1); study.studyStatus(); Study study2 = new Study(); study2.setStudyHours(3); study2.studyStatus(); Study study3 = new Study(); study3.setStudyHours(4); study3.studyStatus(); Study study4 = new Study(); study4.setStudyHours(6); study4.studyStatus(); Study study5 = new Study(); study5.setStudyHours(8); study5.studyStatus(); } }
总结:我们去除了if-else结构使得代码可维护性更强,当我们再添加分支时就会尽可能少的改动原来的代码,但是这种模式也有缺点,会使类的数量增加,增加系统的复杂性,所以我们在开发时需要考虑以后是否会有更多的分支添加进来来决定是否使用该模式。