狀態模式:當一個對象的內在狀態改變時容許改變其行爲,這個對象像是改變了其類。ide
乍一看狀態模式的解釋可能有點不知因此然,其實這個模式並不難理解,首先咱們看一個例子學習
咱們定義了一個學習類,它的一個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(); } }
測試結果:this
學習時間:1,剛開始學習,精力充沛!
學習時間:3,稍有疲憊
學習時間:4,學習效率降低
學習時間:6,學習效率低下
學習時間:8,疲憊不堪spa
咱們假設StudyStatus的study方法內條件分支有不少(雖然我這裏只有5種),當咱們把全部分支條件寫在一個的方法裏時,此時就違反了了「單一職責原則」,除此以外當咱們須要修改某一個分支時,這個方法下的其餘分支也有可能受到影響,這就違反了「開放-封閉原則」,因此咱們作以下改動,首先定義一個狀態的接口,實現類中有一方法studyStatus(),當知足條件是執行操做,不然跳入下一分支。code
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); } }
測試類blog
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結構使得代碼可維護性更強,當咱們再添加分支時就會盡量少的改動原來的代碼,可是這種模式也有缺點,會使類的數量增長,增長系統的複雜性,因此咱們在開發時須要考慮之後是否會有更多的分支添加進來來決定是否使用該模式。接口