咱們是否在敲代碼的過程當中有過在一個類中寫了很是多狀態,是否需要依據該對象的不一樣狀態決定該對象的不一樣行爲。java
如:咱們Android中本身定義一個上拉載入不少其它,下拉刷新的RefreshListView呢?,咱們在RefreshListView中定義了三中狀態。即:下拉刷新狀態。正在刷新,鬆開刷新。而且這三中不一樣的狀態決定了該本身定義控件可否夠下拉等行爲。假如你沒定義過該控件或者沒有寫個那種一個對象有多種狀態相應控制多種行爲也沒關係。因爲狀態模式很是easy,咱們僅僅需要一個樣例就知道怎麼實現狀態模式了。markdown
定義:當一個對象內部狀態改變時贊成改變其行爲,而不用依據不一樣的狀態作過多的if-else推斷。而是用不一樣的類表明不一樣狀態下的行爲,這不一樣的類可以之間不用相互依賴,各自表明不一樣狀態下的行爲。ide
狀態模式使用場景:post
一個對象的行爲取決於它的狀態。而且需要在執行的時候依據不一樣的狀態改變行爲。如:咱們的RefreshListView。假設當前它的狀態是正在刷新,那麼它就不可下拉this
代碼中包括大量與對象狀態相關的if-else語句,一個操做中含有大量的多分支語句if-else或者switch-case語句依賴於該對象的狀態的狀況。假設是這樣的狀況,那麼代碼的可讀性很差,且不易改動維護。spa
狀態模式的長處:code
狀態模式的缺點:對象
代碼實現:接口
電視機行爲接口:圖片
/** * 電視機行爲 * @author lt * */
public interface TvAction {
public void startUp(); // 開機
public void startOff(); // 關機
public void nextChannel(); // 下一個頻道
public void prevChannel(); // 上一個頻道
}
開機狀態行爲:
/** * 電視機開機狀態下的行爲 * @author lt * */
public class TvStartUpState implements TvAction{
/** * 開機,無效 */
@Override
public void startUp() {
}
/** * 關機,有效 */
@Override
public void startOff() {
System.out.println("關機啦!");
}
/** * 下一個頻道,無效 */
@Override
public void nextChannel() {
System.out.println("切換到下一個頻道");
}
/** * 上一個頻道,無效 */
@Override
public void prevChannel() {
System.out.println("切換到上一個頻道");
}
}
關機狀態行爲:
/** * 電視機關機狀態下的行爲 * @author lt * */
public class TvStartOffState implements TvAction{
/** * 開機。有效 */
@Override
public void startUp() {
System.out.println("開機啦。");
}
/** * 關機,無效 */
@Override
public void startOff() {
}
/** * 下一個頻道,無效 */
@Override
public void nextChannel() {
}
/** * 上一個頻道,無效 */
@Override
public void prevChannel() {
}
}
遙控器:
/** * 遙控器 * @author lt * */
public class TvController implements TvAction{
private TvAction tvStartUpState = new TvStartUpState();
private TvAction tvStartOffState = new TvStartOffState();
/** * 電視機的狀態行爲,狀態即行爲,默以爲關機狀態 */
private TvAction tvState = tvStartOffState;
@Override
public void startUp() {
tvState.startUp();
this.tvState = tvStartUpState;
}
@Override
public void startOff() {
tvState.startOff();
this.tvState = tvStartOffState;
}
@Override
public void nextChannel() {
tvState.nextChannel();
}
@Override
public void prevChannel() {
tvState.prevChannel();
}
}
測試:
public class Test {
public static void main(String[] args) {
TvController tvController = new TvController();
// 開機
tvController.startUp();
tvController.nextChannel();
tvController.prevChannel();
// 關機
tvController.startOff();
tvController.nextChannel();
tvController.prevChannel();
// 開機
tvController.startUp();
// 關機
tvController.startOff();
}
}
結果:
狀態模式模擬結束,上面咱們測試的時候,咱們對電視機的狀態頻繁切換,並操做了相應狀態下的行爲,達到了不一樣狀態下對象的行爲改變了。
但你是否在上面所有的代碼你有看到if-else或者switch-case?沒有吧,其實。狀態模式就是爲了不過多的if-else和switch-case語句。上面模擬過程當中咱們看到了電視機的狀態行爲切換如此簡單。
總結:
狀態模式的出現就是爲了解決一個對象多種狀態下不一樣行爲表現致使出現過多的if-else或者switch-case語句推斷切換不一樣狀態下的行爲, 一般這樣的作法需要設置一個變量記錄該對象當前的狀態,而後依據變量執行不一樣的代碼。而狀態模式根本就不需要if-else和switch-case,一個對象類表明一種狀態下的行爲表現。當狀態切換時切換不一樣的對象類就能夠,達到狀態即行爲的效果。
狀態模式的使用和沒有使用狀態模式的if-else/switch-case控制行爲的關係有點像c是面向過程而java面向對象的關係同樣。