1、對象狀態影響對象行爲
對象擁有不一樣的狀態,每每會行使不一樣的行爲...
2、動機(Motivation)
1)在軟件構建過程當中,某些對象的狀態若是改變,其行爲也會隨之而發生變化,好比文檔處於只讀狀態,其支持的行爲和讀寫狀態支持的行爲就可能徹底不一樣。
2)如何在運行時根據對象的狀態來透明地更改對象的行爲?而不會爲對象操做和狀態轉化之間引入緊耦合?
3、意圖(Intent)
容許一個對象在其內部狀態改變時改變它的行爲。從而使對象看起來彷佛修改了其行爲。
——《設計模式》GoF
4、實例:文檔的處理(讀/寫)
1)最初的設計
//文檔的幾種狀態用枚舉列舉出來,若是枚舉穩定,這樣設計很好
public enum DocumentState
{
ReadOnly,
Edittable,
}設計模式
public class Document
{
DocumentState state;
public Document(DocumentState state)
{
this.state = state;
}
//若是修改DocumentState,好比加一種狀態,這裏也要修改Handle方法
public void Handle()
{
//使用is-else切換狀態,若是這種切換頻繁,而且有新的狀態加入,這時應考慮State模式了
if (state == DocumentState.ReadOnly)
{
}
else if (state == DocumentState.Edittable)
{
}
}
} ide
2)演化到State模式:
與策略模式類似,但又不一樣,狀態模式最主要是可以在各狀態之間自由切換
//抽象類:表達狀態及依賴狀態的行爲
public abstract class StatedDocument
{
//屬性:指定下一個狀態
public abstract StatedDocument Next
{
get;
set;
}
public abstract void Handle1();
public abstract void Handle2();
public abstract void Handle3();
}this
//只讀狀態
public class ReadOnlyState : StatedDocument
{
private StatedDocument next = new ReadWriteState();
//切換到下個狀態,這裏寫死了,切換到讀寫狀態,固然能夠根據須要設計出切換到任何狀態的代碼
public override StatedDocument Next
{
get
{
return this.next;
}
set
{
this.next = value;
}
}
public override void Handle1(){}
public override void Handle2(){}
public override void Handle3(){}
}設計
//讀寫狀態
public class ReadWriteState : StatedDocument
{
private StatedDocument next = new ReadOnlyState();
//切換到下個狀態,這裏寫死了,切換到只讀狀態
public override StatedDocument Next
{
get
{
return this.next;
}
set
{
this.next = value;
}
}
public override void Handle1(){}
public override void Handle2(){}
public override void Handle3(){}
}對象
//主邏輯:依賴的是一個抽象類StatedDocument
public class Document
{
StatedDocument statedDocument;
public void SetStatedDocument(StatedDocument statedDocument)
{
this.statedDocument = statedDocument
}
public void Handle1()
{
statedDocument.Handle1();
//根據須要是切換仍是不切換狀態
statedDocument = statedDocument.Next;
}
public void Handle2()
{
statedDocument.Handle2();
}
public void Handle3()
{
statedDocument.Handle3();
}
}接口
5、State模式的幾個要點
1)State模式將全部與一個特定狀態相關的行爲都放入一個State的子類對象中,在對象狀態切換時,切換相應的對象;但同時維持State的接口,這樣實現了具體操做與狀態轉換之間的解耦。
2)爲不一樣的狀態引入不一樣的對象使得狀態轉換變得更加明確,並且能夠保證不會出現狀態不一致的狀況,由於轉換是原子性的——即要麼完全轉換過來,要麼不轉換。
3)若是State對象沒有實例變量,那麼各個上下文能夠共享同一個State對象,從而節省對象開銷。文檔