1. 程式人生 > >設計模式--狀態模式State(行為型)

設計模式--狀態模式State(行為型)

1 定義:

1.1 定義:Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.(當一個物件內在狀態改變時允許其改變行為,這個物件看起來像改變了其類)

1.2 通用類圖:

一個更易理解的類圖:

角色解說:

State——抽象狀態角色

介面或抽象類,負責物件狀態定義,並且封裝環境角色以實現狀態切換。

ConcreteState——具體狀態角色

每一個具體狀態必須完成兩個職責:本狀態行為管理以及趨向狀態處理,通俗地說,就是本狀態下要做的事情,以及本狀態如何過渡到其他狀態。

Context——環境角色

定義客戶端需要的介面,並且負責具體狀態的切換。

1.3 通用程式碼:

public abstract class State {
	// 定義一個環境角色,提供子類訪問
	protected Context context;

	// 設定環境角色
	public void setContext(Context _context) {
		this.context = _context;
	}

	// 行為1
	public abstract void handle1();

	// 行為2
	public abstract void handle2();
}

public class ConcreteState1 extends State {
	@Override
	public void handle1() {
		// 本狀態下必須處理的邏輯
	}

	@Override
	public void handle2() {
		// 設定當前狀態為stat2
		super.context.setCurrentState(Context.STATE2);
		// 過渡到state2狀態,由Context實現
		super.context.handle2();
	}
}

public class ConcreteState2 extends State {
	@Override
	public void handle1() {
		// 設定當前狀態為stat1
		super.context.setCurrentState(Context.STATE1);
		// 過渡到state1狀態,由Context實現
		super.context.handle1();
	}

	@Override
	public void handle2() {
		// 本狀態下必須處理的邏輯
	}
}

public class Context {
	// 定義狀態
	public final static State STATE1 = new ConcreteState1();
	public final static State STATE2 = new ConcreteState2();
	// 當前狀態
	private State CurrentState;

	// 獲得當前狀態
	public State getCurrentState() {
		return CurrentState;
	}

	// 設定當前狀態
	public void setCurrentState(State currentState) {
		this.CurrentState = currentState;
		// 切換狀態
		this.CurrentState.setContext(this);
	}

	// 行為委託
	public void handle1() {
		this.CurrentState.handle1();
	}

	public void handle2() {
		this.CurrentState.handle2();
	}
}

public class Client {
	public static void main(String[] args) {
		// 定義環境角色
		Context context = new Context();
		// 初始化狀態
		context.setCurrentState(new ConcreteState1());
		// 行為執行
		context.handle1();
		context.handle2();
	}
}

2 優點

2.1 結構清晰:避免了過多的條件判斷,避免了程式的複雜性,提高了系統的可擴充套件性。

2.2 遵循開閉原則單一職責原則:每個狀態都是一個子類,要增加狀態就要增加子類,修改狀態,就只需修改一個子類就可以了。

2.3 封裝性非常好:狀態變換放置到類的內部來實現,外部的呼叫不用知道類內部如何實現狀態和行為的變換。

3 缺點

子類會太多,即類膨脹。這時可以採用狀態表,然後根據狀態執行相應的操作。

4 應用場景

4.1 行為隨狀態改變而改變的場景:如許可權設計(人員的狀態不同,即使執行相同的行為,結果也不同);

4.2 條件、分支判斷語句的替代者(有待思量)

5 注意事項

狀態模式適用於當某個物件在它的狀態發生改變時,它的行為也隨著發生比較大的變化,也就是說行為受狀態約束的情況下可以使用狀態模式,而且使用時,物件的狀態最好不要超過5

個。

6 擴充套件

7 範例

做個網狀多狀態切換的,最好用狀態表來做。。。。