一、簡介ide
在平常開發中,某些對象的狀態若是發生改變,對應的行爲也將發生改變,那麼如何在運行時根據對象的狀態動態的改變對象的行爲,同時不產生緊耦合關係(即便用if else或者swith所帶來的緊耦合關係).即對擴展開放,對修改關閉一開閉原則.函數
二、案例測試
假設用戶提出了一個需求,有三類文檔對象,他們都由Read、Update、Write的功能,且分爲只讀文檔、只改文檔、只寫文檔,且在編寫代碼時,他們的RUW(R-Read)功能各不相同,即每一類的狀態文檔,在運行時,他們的Read、Write、Update的代碼邏輯各不相同,這個時候該如何經過狀態模式編寫代碼,很顯然,若是不用State模式,能夠經過if else或者swith能夠很輕鬆的完成需求.可是那樣的代碼耦合度高,且修改時,代價太大,容易影響現有代碼的邏輯,給測試增長壓力,由於你每一次對單一文檔對象的修改都會影響其餘全部文檔對象的運行.下面使用State狀態模式來完成這個需求.spa
三、代碼實戰code
public static void Main(string[] args) { var manager = new DocumentManage(new ReadOnlyDocument()); var content=manager.Read(); Console.WriteLine(content); Console.ReadKey(); } /// <summary> /// 狀態文檔方法約束接口 /// </summary> public interface IStatedDocument { string Read(); void Write(); void Update(); } /// <summary> /// 抽象狀態文檔對象 /// </summary> public abstract class StatedDocument: IStatedDocument { public abstract string Read(); public abstract void Write(); public abstract void Update(); } /// <summary> /// 只讀文檔對象 /// </summary> public class ReadOnlyDocument : StatedDocument { public override string Read() { return "只讀文檔內容"; } public override void Update() { throw new Exception("只讀文檔,沒法修改其內容"); } public override void Write() { throw new Exception("只讀文檔,沒法寫入內容"); } } /// <summary> /// 文檔管理對象 /// </summary> public class DocumentManage: IStatedDocument { private StatedDocument _statedDocument; /// <summary> /// 能夠經過構造函數傳入具體的文檔,或者Set方法 /// </summary> public DocumentManage(StatedDocument statedDocument) { _statedDocument = statedDocument; } public string Read() { return _statedDocument.Read(); } public void Update() { _statedDocument.Update(); } public void Write() { _statedDocument.Write(); } }
ok,能夠看到state狀態模式很好的完成了需求,並且每當用戶提出一種新的需求,如編寫一個只讀只寫文檔,你就能夠經過擴展類的方式,經過編寫一個只讀只寫文檔類,來完成他的需求,並且每次發佈模塊,只須要測新類型的功能是否ok,不須要測其餘的功能,由於狀態模式是符合開閉原則,對擴展方法,對修改關閉.且全部的上下文共享一個State對象,各個狀態文檔對象經過子類的方法展示,若是狀態發生改變,那麼其狀態下的方法全都會改變.對象