天天看點

狀态模式 - 行為模式

個人了解:    

模式類型:

    State  狀态模式 - 行為模式

意圖:

    Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

    An object-oriented state machine

    wrapper + polymorphic wrappee + collaboration

    當一個對象的内在狀态改變時允許改變其行為,這個對象看起來像是改變了其類。又稱狀态對象模式(Pattern of Objects for States),狀态模式是對象的行為模式。

概述:

    主要解決的是當控制一個對象狀态轉換的條件表達式過于複雜時的情況。把狀态的判斷邏輯轉移到表示不同的一系列類當中,可以把複雜的邏輯判斷簡單化。

    在很多情況下,一個對象的行為取決于一個或多個動态變化的屬性,這樣的屬性叫做狀态,這樣的對象叫做有狀态的(stateful)對象,這樣的對象狀态是從事先定義好的一系列值中取出的。當一個這樣的對象與外部事件産生互動時,其内部狀态就會改變,進而使得系統的行為也随之發生變化。

角色:

    上下文環境(Context):它定義了客戶程式需要的接口并維護一個具體狀态角色的執行個體,将與狀态相關的操作委托給目前的Concrete State對象來處理。

    抽象狀态(State):定義一個接口以封裝使用上下文環境的的一個特定狀态相關的行為。

    具體狀态(Concrete State):實作抽象狀态定義的接口。

結構圖:

狀态模式 - 行為模式

模式的應用場景:

當一個對象的行為取決于它的狀态,并且它必須在運作時刻根據狀态改變它的行為時,就可以考慮使用狀态模式來。

一個操作中含有龐大的分支結構,并且這些分支決定于對象的狀态。

模式的優缺點:

狀态模式的優點:

    1 ) 它将與特定狀态相關的行為局部化,并且将不同狀态的行為分割開來: State模式将所有與一個特定的狀态相關的行為都放入一個對象中。因為所有與狀态相關的代碼都存在于某一個State子類中, 是以通過定義新的子類可以很容易的增加新的狀态和轉換。另一個方法是使用資料值定義内部狀态并且讓 Context操作來顯式地檢查這些資料。但這樣将會使整個Context的實作中遍布看起來很相似的條件if else語句或switch case語句。增加一個新的狀态可能需要改變若幹個操作, 這就使得維護變得複雜了。State模式避免了這個問題, 但可能會引入另一個問題, 因為該模式将不同狀态的行為分布在多個State子類中。這就增加了子類的數目,相對于單個類的實作來說不夠緊湊。但是如果有許多狀态時這樣的分布實際上更好一些, 否則需要使用巨大的條件語句。正如很長的過程一樣,巨大的條件語句是不受歡迎的。它們形成一大整塊并且使得代碼不夠清晰,這又使得它們難以修改和擴充。 State模式提供了一個更好的方法來組織與特定狀态相關的代碼。決定狀态轉移的邏輯不在單塊的 i f或s w i t c h語句中, 而是分布在State子類之間。将每一個狀态轉換和動作封裝到一個類中,就把着眼點從執行狀态提高到整個對象的狀态。這将使代碼結構化并使其意圖更加清晰。

    2) 它使得狀态轉換顯式化: 當一個對象僅以内部資料值來定義目前狀态時 , 其狀态僅表現為對一些變量的指派,這不夠明确。為不同的狀态引入獨立的對象使得轉換變得更加明确。而且, State對象可保證Context不會發生内部狀态不一緻的情況,因為從 Context的角度看,狀态轉換是原子的—隻需重新綁定一個變量(即Context的State對象變量),而無需為多個變量指派

    3) State對象可被共享 如果State對象沒有執行個體變量—即它們表示的狀态完全以它們的類型來編碼—那麼各Context對象可以共享一個State對象。當狀态以這種方式被共享時, 它們必然是沒有内部狀态, 隻有行為的輕量級對象。

狀态模式的缺點:

    1) 狀态模式的使用必然會增加系統類和對象的個數。

    2) 狀态模式的結構與實作都較為複雜,如果使用不當将導緻程式結構和代碼的混亂。

代碼(其實讀UML圖要比代碼還要一目了然):

狀态模式 - 行為模式
package com.lee.desingerPattener23.state;

public class StatePatternDemo {
	public static void main(String[] args) {
		Context context = new Context();
		StartState startState = new StartState();
		startState.doAction(context);
		System.out.println(context.getState().toString());

		StopState stopState = new StopState();
		stopState.doAction(context);
		System.out.println(context.getState().toString());
	}
}
interface State {
	public void doAction(Context context);
}
class Context {
	private State state;
	public Context() {
		state = null;
	}
	public void setState(State state) {
		this.state = state;
	}
	public State getState() {
		return state;
	}
}
class StartState implements State {
	public void doAction(Context context) {
		System.out.println("Player is in start state");
		context.setState(this);
	}
	public String toString() {
		return "Start State";
	}
}

class StopState implements State {
	public void doAction(Context context) {
		System.out.println("Player is in stop state");
		context.setState(this);
	}
	public String toString() {
		return "Stop State";
	}
}
           

所有模式:

     建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:擴充卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

    行為型模式,共十一種:政策模式、模闆方法模式、觀察者模式、疊代子模式、責任鍊模式、指令模式、備忘錄模式、狀态模式、通路者模式、中介者模式、解釋器模式。

    補充模式:空對象模式

參考/轉自:

https://sourcemaking.com/design_patterns/state

http://www.cnblogs.com/xudong-bupt/p/3617860.html

http://www.cnblogs.com/wangjq/archive/2012/07/16/2593485.html

http://blog.csdn.net/hguisu/article/details/7557252

轉載請注明:   http://blog.csdn.net/paincupid/article/details/46984077

繼續閱讀