java设计模式--[行为模式]--状态模式[state pattern]
一. 狀態模式
允許一個對象在其內部狀態改變時改變它的行為.這個對象看起來似乎修改了它的類.看起來,狀態模式好像是神通廣大--居然可以修改自身的類!
二. 狀態模式包括三個角色:
1. 環境: 環境是一個類,該類含有抽象狀態聲明的變量,可以引用任何具體狀態類的實例.
2. 抽象狀態: 抽象狀態是一個接口或抽象類,定義了與環境的一個特定狀態相關的若干方法.
3.具體狀態: 具體狀態是實現(擴展)旬狀態(抽象類)的類.
三. 狀態模式的UML類圖如下:
四. 下面以一個冬簡單的實例來說明狀態的切換:
一個彈夾可以裝3顆子彈,每次發射一顆,全發射完后,可以重新裝滿3顆子彈,其狀態轉換圖如下所示:
五. 完整的示例代碼如下:
1. 環境類:
package behavioralPattern.state.state1;
/**
* @ClassName: Gun
* @Description:槍類[context]
* @author Liyongbin
* @date 2011-2-9 下午05:07:17
* @version V1.0
*/
public class Gun {
private IState state, state0, state1, state2, state3;
public Gun() {
//無子彈
state0 = new State0Bullet(this);
//1顆子彈
state1 = new State1Bullet(this);
//2顆子彈
state2 = new State2Bullet(this);
//3顆子彈
state3 = new State3Bullet(this);
//默認情況下有3顆子彈
state = state3;
}
//發射子彈
public void fire(){
state.fire();
}
public IState getState() {
return state;
}
public void setState(IState state) {
this.state = state;
}
public IState getState0() {
return state0;
}
public void setState0(IState state0) {
this.state0 = state0;
}
public IState getState1() {
return state1;
}
public void setState1(IState state1) {
this.state1 = state1;
}
public IState getState2() {
return state2;
}
public void setState2(IState state2) {
this.state2 = state2;
}
public IState getState3() {
return state3;
}
public void setState3(IState state3) {
this.state3 = state3;
}
}
2. 抽象狀態類:
package behavioralPattern.state.state1;
/**
* @ClassName: IState
* @Description:狀態[State]
* @author Liyongbin
* @date 2011-2-9 下午05:08:49
* @version V1.0
*/
public interface IState {
//發射
public void fire();
//裝子彈
public void loadBullet();
//顯示狀態信息
public String message();
}
3. 無子彈狀態
package behavioralPattern.state.state1;
/**
* @ClassName: State2Bullet
* @Description:無子彈狀態
* @author Liyongbin
* @date 2011-2-9 下午05:15:56
* @version V1.0
*/
public class State0Bullet implements IState {
private Gun gun;
public State0Bullet(Gun gun) {
this.gun = gun;
}
//發射子彈
@Override
public void fire() {
//當前的狀態
System.out.print("裝滿三顆子彈!");
//獲取下一個狀態
this.gun.setState(gun.getState3());
//輸出要進入狀態的信息
System.out.println("進入"+"["+gun.getState3().message()+"]");
}
//能否裝彈
@Override
public void loadBullet() {
System.out.println("可以裝子彈.");
}
//當前狀態信息
@Override
public String message() {
return "無顆子彈狀態";
}
}
4. 1顆子彈狀態
package behavioralPattern.state.state1;
/**
* @ClassName: State1Bullet
* @Description:1顆子彈狀態
* @author Liyongbin
* @date 2011-2-9 下午05:16:10
* @version V1.0
*/
public class State1Bullet implements IState {
private Gun gun;
public State1Bullet(Gun gun){
this.gun = gun;
}
//發射子彈
@Override
public void fire() {
//當前的狀態
System.out.print("射出最后一顆子彈!");
//獲取下一個狀態
this.gun.setState(gun.getState0());
//輸出要進入狀態的信息
System.out.println("進入"+"["+gun.getState0().message()+"]");
}
//能否裝彈
@Override
public void loadBullet() {
System.out.println("不能裝子彈.");
}
//當前狀態信息
@Override
public String message() {
return "1顆子彈狀態";
}
}
5. 2顆子彈狀態
package behavioralPattern.state.state1;
/**
* @ClassName: State2Bullet
* @Description:2顆子彈狀態
* @author Liyongbin
* @date 2011-2-9 下午05:15:56
* @version V1.0
*/
public class State2Bullet implements IState {
private Gun gun;
public State2Bullet(Gun gun){
this.gun = gun;
}
//發射子彈
@Override
public void fire() {
//當前的狀態
System.out.print("射出一顆子彈!");
//獲取下一個狀態
this.gun.setState(gun.getState1());
//輸出要進入狀態的信息
System.out.println("進入"+"["+gun.getState1().message()+"]");
}
//能否裝彈
@Override
public void loadBullet() {
System.out.println("不能裝子彈.");
}
//當前狀態信息
@Override
public String message() {
return "2顆子彈狀態";
}
}
6. 3顆子彈狀態
package behavioralPattern.state.state1;
/**
* @ClassName: State3Bullet
* @Description:3顆子彈狀態
* @author Liyongbin
* @date 2011-2-9 下午05:15:26
* @version V1.0
*/
public class State3Bullet implements IState {
private Gun gun;
public State3Bullet(Gun gun){
this.gun = gun;
}
//發射子彈
@Override
public void fire() {
//當前的狀態
System.out.print("射出一顆子彈!");
//獲取下一個狀態
this.gun.setState(gun.getState2());
//輸出要進入狀態的信息
System.out.println("進入"+"["+gun.getState2().message()+"]");
}
//能否裝彈
@Override
public void loadBullet() {
System.out.println("不能裝子彈.");
}
//當前狀態信息
@Override
public String message() {
return "3顆子彈狀態";
}
}
7. 測試類
package behavioralPattern.state.state1;
/**
* @ClassName: StateTest
* @Description:狀態模式測試
* @author Liyongbin
* @date 2011-2-9 下午06:01:21
* @version V1.0
*/
public class StateTest {
public static void main(String[] args) {
Gun gun = new Gun();
gun.fire();
gun.fire();
gun.fire();
gun.fire();
gun.fire();
gun.fire();
gun.fire();
}
}
8.測試結果如下: