狀態模式:當一個對象的內在狀態改變時容許改變其行爲,這個對象看起來像是改變了其類。安全
狀態模式主要解決的是當控制一個對象狀態的條件表達式過於複雜時的狀況。把狀態的判斷邏輯轉移到表示不一樣狀態的一系列類中,能夠把複雜的判斷邏輯簡化。ide
那麼爲何必需要狀態模式,不用狀態模式能夠嗎?固然能夠,可是仍是回到了代碼的可維護性、可擴展性、可複用性這個層面上來考慮問題。好比一個車,不一樣的檔位下轉速、車速等是不同的,固然咱們能夠在每一個方法中判斷當前檔位來控制車的狀態,可是檔位愈來愈多的時候呢,咱們就會在每一個方法嵌套大量的ifelse,這無疑是很是糟糕的代碼,可讀性很是的差,而且若是需求發生了改變,咱們很難去修改代碼(很容易出現錯誤),可是若是咱們考慮將這些狀態都做爲一個類,在每個類內部進行處理、判斷和相應的切換,這樣思路就很是的清晰,若是再增長一種狀態,代碼須要修改的地方會很是的少,對於狀態很是多的情景來講很是的方便。學習
狀態模式比較容易理解,類圖也比較簡單this
下面就車換擋的例子作一個demospa
package state; public interface State { void speed(); void rotateSpeed(); }
package state; public class FristGear implements State{ @Override public void speed() { System.out.println("速度10"); } @Override public void rotateSpeed() { System.out.println("轉速10"); } }
package state; public class SecondGear implements State { @Override public void speed() { System.out.println("速度20"); } @Override public void rotateSpeed() { System.out.println("轉速20"); } }
package state; public class ThridGear implements State { @Override public void speed() { System.out.println("速度30"); } @Override public void rotateSpeed() { System.out.println("轉速30"); } }
package state; public class Car { public static final State fristGear = new FristGear(); public static final State secondGear = new SecondGear(); public static final State thirdGear = new ThridGear(); private State state = fristGear; public void setState(State state) { this.state = state; } public void carState() { System.out.println("當前車狀態:"); state.speed(); state.rotateSpeed(); } }
package state; public class Client { public static void main(String[] args) { Car car = new Car(); car.carState(); car.setState(Car.secondGear); car.carState(); car.setState(Car.thirdGear); car.carState(); } }
狀態模式的優勢code
一、每一個狀態的行爲局部化到它本身的類中對象
二、將容易產生問題的if else結構去掉,使得代碼的可維護性更強,不易出錯。blog
三、使用多態代替了條件判斷,這樣咱們代碼的擴展性更強,當要增長一些狀態時,會很是的容易。接口
四、讓每個狀態對修改關閉,對擴展開放class
五、狀態是能夠被共享的,這個在上面的例子當中有體現,看下Car類當中的幾個static final變量就知道了,由於狀態類通常是沒有本身的內部狀態的,全部它只是一個具備行爲的對象,所以是能夠被共享的。
六、狀態的轉換更加簡單安全,簡單體如今狀態的分割,由於咱們把一堆if else分割成了若干個代碼段分別放在幾個具體的狀態類當中,因此轉換起來固然更簡單,並且每次轉換的時候咱們只須要關注一個固定的狀態到其餘狀態的轉換。安全體如今類型安全,咱們設置狀態時,必須是狀態接口的實現類,這能夠杜絕數不正確的狀態碼。
相信你們在學習狀態模式ai時候都會有一個疑問:狀態模式和策略模式有什麼區別。在這裏說下個人理解,二者在類圖和結構基本同樣,不一樣的是使用場景的側重點,狀態模式更強調的是隨着外部條件的變化,狀態對象內部的方法作出不一樣的動做;策略模式側重的是根據外部條件選取一個合適的策略來執行動做,並作出的對應的響應。策略模式中咱們的策略類一般只有一個方法,而咱們的狀態類通常則可能有多個方法,來更全面的展現狀態對象。