State(狀態)模式 – 2

來源:互聯網
上載者:User
原帖地址;http://luoji10000.blog.163.com/blog/static/166439382201068104029647/
State(狀態)模式 - 2


行為型模式
2010-07-08 10:40:29
閱讀23

評論0


  字型大小:大



 
訂閱


如果您不瞭解TCP的連線方式,在看Gof的書介紹 State 狀態模式

時,大概會看得一頭霧水吧! TCP的連線狀態圖,光是要瞭解就要花點精神了,它的連線狀態很多,用來說明狀態模式確實很適合,但不適合教導初學模式的人.

簡單的開始會比較好理解狀態模式的作用,先來看一個例子,如果您有一個只能順時針轉動的瓦斯開關,轉動一次的狀態為off, small
fire,medium fire與large
fire,您如何在程式中控制狀態的變化與行為呢?一個最簡單的方式就是用if...else...或是switch流程來控制,例如:
State.java

public class State {

private int state; 

public State() { 

state = 0;



public void switchFire() {

if (state == 0) { 

state = 1; System.out.println( "small fire" ); 

} else if (state == 1) { 

state = 2; System.out.println( "medium fire" ); 

} else if (state == 2) { 

state = 3; System.out.println( "large fire" ); } else { 

state = 0; System.out.println( "turning off" ); } 



}

Main.java

public class Main {

public static void main(String[] args) { 

State state = new State(); 

state.switchFire(); 

state.switchFire();

state.switchFire(); 

state.switchFire(); } 

}


個方法很簡單,每個人都會,但如果您的狀態變化並不是流水式的變化,而是像TCP連線狀態一樣,會是一個網狀圖的時候,用if...else或
switch來寫的話,您的程式就會亂的不像話了;來考慮如何讓物件控制自己的狀態轉換與所應表現的行為,這個程式可以這樣改寫:
IState.java

public interface IState { public void switchFire(FireSwitch sw); }

OffState

public class OffState implements IState {

public void switchFire(FireSwitch sw) { 

sw.setState(new SmallState()); 

System.out.println( "small fire" ); } 

}

SmallState.java

public class SmallState implements IState { 

public void switchFire(FireSwitch sw) { 

sw.setState(new MediumState()); 

System.out.println( "medium fire" ); }

}

MediumState.java

public class MediumState implements IState { 

public void switchFire(FireSwitch sw) {

sw.setState(new LargeState()); 

System.out.println( "large fire" ); }

}

LargeState.java

public class LargeState implements IState { 

public void switchFire(FireSwitch sw) {

sw.setState(new OffState()); System.out.println( "off fire" ); } 

}

FireSwitch.java

public class FireSwitch { 

private State current;

public FireSwitch() { current = new OffState(); } 

public void setState(State s) { current = s; } 

public void switchFire() { current.switchFire(this); }

}

Main.java

public class Main { 

public static void main(String[] args) {

FireSwitch fireSwitch = new FireSwitch();

fireSwitch.switchFire(); 

fireSwitch.switchFire(); 

fireSwitch.switchFire();

fireSwitch.switchFire(); } 

}

程式執行結果與上一個例子是一樣的,但這次並沒有用流程式控制制來進行狀態轉換,而由物件自行控制自己的狀態,與必須表現的行為,這個方式就是State模式,將這個例子的UML類別結構畫出就如下所示:

再進一步考慮開關可以順時針與逆時針轉動,這時如果您仍以if...else或switch來寫,就會讓流程顯示複雜,來看看如何使用狀態模式來撰寫:
IState.java

public interface IState { 

public void switchClockWise(FireSwitch sw); 

public void switchCountClock(FireSwitch sw); 

}

OffState.java

public
class OffState implements IState { public void
switchClockWise(FireSwitch sw) { sw.setState(new SmallState());
System.out.println("small fire"); } public void
switchCountClock(FireSwitch sw) { sw.setState(new LargeState());
System.out.println("large fire"); } }

SmallState.java

public class SmallState implements IState {

public void switchClockWise(FireSwitch sw) { sw.setState(new MediumState()); System.out.println("medium fire"); } 

public void switchCountClock(FireSwitch sw) { sw.setState(new OffState()); System.out.println("off fire"); } 

}

MediumState.java

public class MediumState implements IState { 

public
void switchClockWise(FireSwitch sw) { sw.setState(new LargeState());
System.out.println("large fire"); } public void
switchCountClock(FireSwitch sw) { sw.setState(new SmallState());
System.out.println("small fire"); } 

}

LargeState.java

public class LargeState implements State {

public void switchClockWise(FireSwitch sw) { sw.setState(new OffState()); System.out.println("off fire"); } 

public void switchCountClock(FireSwitch sw) { sw.setState(new MediumState()); System.out.println("mediumfire"); } 

}

FireSwitch.java

public class FireSwitch { 

private State current; 

public FireSwitch() { current = new OffState(); } 

public void setState(State s) { current = s; } 

public void switchClockWise() { current.switchClockWise(this); }

public void switchCountClock() { current.switchCountClock(this); }

}

Main.java

public class Main { 

public static void main(String[] args) { 

FireSwitch fireSwitch = new FireSwitch();

fireSwitch.switchClockWise(); 

fireSwitch.switchClockWise(); 

fireSwitch.switchClockWise(); 

fireSwitch.switchClockWise(); 

System.out .println(); 

fireSwitch.switchCountClock(); 

fireSwitch.switchCountClock(); 

fireSwitch.switchCountClock(); 

fireSwitch.switchCountClock(); } 

}


下來您可以任意的轉動開關了,無論是順時針轉動或是逆時針轉動,狀態的轉換都由物件自己來表現,這是雙向狀態轉換下的例子,如果一個狀態可能轉換至三個以
上的狀態,使用State模式就更可以看出它的好處了,就像Gof的TCP連線例子一樣,如果您瞭解TCP連線,可以看看原書是如何?TCP連線之間的
狀態轉換的.
State模式的UML結構圖如下:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.