41状态模式(State Pattern)
對象狀態影響對象行為:
??? 對象擁有不同的狀態,往往會行使不同的行為...
??? ?? ??? ??? ? ??
動機:
??? 在軟件構建過程中,某些對象的狀態如果改變以及其行為也會隨之而發生變化,比如文檔處于只讀狀態,其支持的行為和讀寫狀態支持的行為就可能完全不同。
??? 如何在運行時根據對象的狀態來透明更改對象的行為?而不會為對象操作和狀態轉化之間引入緊耦合?
意圖:
?允許一個對象在其內部狀態改變時改變它的行為。從而使對象看起來似乎修改了其行為。? ------《設計模式》GOF
結構圖:
????
適用性:
??? 1.一個對象的行為取決于它的狀態,并且它必須在運行時刻根據狀態改變它的行為。
2.一個操作中含有龐大的多分支的等條件語句,且這些分支依賴于該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常,有多個操作包含這一相同的條件結構。State模式將每一個分支放入一個獨立的類中。這使得你可根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴于其他對象而獨立變化。
代碼實現:
????
?
??class?MainApp
??{
????static?void?Main()
????{
??????//?Open?a?new?account
??????Account?account?=?new?Account("Jim?Johnson");
??????//?Apply?financial?transactions
??????account.Deposit(500.0);
??????account.Deposit(300.0);
??????account.Deposit(550.0);
??????account.PayInterest();
??????account.Withdraw(2000.00);
??????account.Withdraw(1100.00);
??????//?Wait?for?user
??????Console.Read();
????}
??}
??//?"State"
??abstract?class?State
??{
????protected?Account?account;
????protected?double?balance;
????protected?double?interest;
????protected?double?lowerLimit;
????protected?double?upperLimit;
????//?Properties
????public?Account?Account
????{
??????get{?return?account;?}
??????set{?account?=?value;?}
????}
????public?double?Balance
????{
??????get{?return?balance;?}
??????set{?balance?=?value;?}
????}
????public?abstract?void?Deposit(double?amount);
????public?abstract?void?Withdraw(double?amount);
????public?abstract?void?PayInterest();
??}
??//?"ConcreteState"
??//?Account?is?overdrawn
??class?RedState?:?State
??{
????double?serviceFee;
????//?Constructor
????public?RedState(State?state)
????{
??????this.balance?=?state.Balance;
??????this.account?=?state.Account;
??????Initialize();
????}
????private?void?Initialize()
????{
??????//?Should?come?from?a?datasource
??????interest?=?0.0;
??????lowerLimit?=?-100.0;
??????upperLimit?=?0.0;
??????serviceFee?=?15.00;
????}
????public?override?void?Deposit(double?amount)
????{
??????balance?+=?amount;
??????StateChangeCheck();
????}
????public?override?void?Withdraw(double?amount)
????{
??????amount?=?amount?-?serviceFee;
??????Console.WriteLine("No?funds?available?for?withdrawal!");
????}
????public?override?void?PayInterest()
????{
??????//?No?interest?is?paid
????}
????private?void?StateChangeCheck()
????{
??????if?(balance?>?upperLimit)
??????{
????????account.State?=?new?SilverState(this);
??????}
????}
??}
??//?"ConcreteState"
??//?Silver?is?non-interest?bearing?state
??class?SilverState?:?State
??{
????//?Overloaded?constructors
????public?SilverState(State?state)?:
??????this(?state.Balance,?state.Account)
????{??
????}
????public?SilverState(double?balance,?Account?account)
????{
??????this.balance?=?balance;
??????this.account?=?account;
??????Initialize();
????}
????private?void?Initialize()
????{
??????//?Should?come?from?a?datasource
??????interest?=?0.0;
??????lowerLimit?=?0.0;
??????upperLimit?=?1000.0;
????}
????public?override?void?Deposit(double?amount)
????{
??????balance?+=?amount;
??????StateChangeCheck();
????}
????public?override?void?Withdraw(double?amount)
????{
??????balance?-=?amount;
??????StateChangeCheck();
????}
????public?override?void?PayInterest()
????{
??????balance?+=?interest?*?balance;
??????StateChangeCheck();
????}
????private?void?StateChangeCheck()
????{
??????if?(balance?<?lowerLimit)
??????{
????????account.State?=?new?RedState(this);
??????}
??????else?if?(balance?>?upperLimit)
??????{
????????account.State?=?new?GoldState(this);
??????}
????}
??}
??//?"ConcreteState"
??//?Interest?bearing?state
??class?GoldState?:?State
??{
????//?Overloaded?constructors
????public?GoldState(State?state)
??????:?this(state.Balance,state.Account)
????{??
????}
????public?GoldState(double?balance,?Account?account)
????{
??????this.balance?=?balance;
??????this.account?=?account;
??????Initialize();
????}
????private?void?Initialize()
????{
??????//?Should?come?from?a?database
??????interest?=?0.05;
??????lowerLimit?=?1000.0;
??????upperLimit?=?10000000.0;
????}
????public?override?void?Deposit(double?amount)
????{
??????balance?+=?amount;
??????StateChangeCheck();
????}
????public?override?void?Withdraw(double?amount)
????{
??????balance?-=?amount;
??????StateChangeCheck();
????}
????public?override?void?PayInterest()
????{
??????balance?+=?interest?*?balance;
??????StateChangeCheck();
????}
????private?void?StateChangeCheck()
????{
??????if?(balance?<?0.0)
??????{
????????account.State?=?new?RedState(this);
??????}
??????else?if?(balance?<?lowerLimit)
??????{
????????account.State?=?new?SilverState(this);
??????}
????}
??}
??//?"Context"
??class?Account
??{
????private?State?state;
????private?string?owner;
????//?Constructor
????public?Account(string?owner)
????{
??????//?New?accounts?are?'Silver'?by?default
??????this.owner?=?owner;
??????state?=?new?SilverState(0.0,?this);
????}
????//?Properties
????public?double?Balance
????{
??????get{?return?state.Balance;?}
????}
????public?State?State
????{
??????get{?return?state;?}
??????set{?state?=?value;?}
????}
????public?void?Deposit(double?amount)
????{
??????state.Deposit(amount);
??????Console.WriteLine("Deposited?{0:C}?---?",?amount);
??????Console.WriteLine("?Balance?=?{0:C}",?this.Balance);
??????Console.WriteLine("?Status?=?{0}\n"?,
????????this.State.GetType().Name);
??????Console.WriteLine("");
????}
????public?void?Withdraw(double?amount)
????{
??????state.Withdraw(amount);
??????Console.WriteLine("Withdrew?{0:C}?---?",?amount);
??????Console.WriteLine("?Balance?=?{0:C}",?this.Balance);
??????Console.WriteLine("?Status?=?{0}\n"?,
????????this.State.GetType().Name);
????}
????public?void?PayInterest()
????{
??????state.PayInterest();
??????Console.WriteLine("Interest?Paid?---?");
??????Console.WriteLine("?Balance?=?{0:C}",?this.Balance);
??????Console.WriteLine("?Status?=?{0}\n"?,
????????this.State.GetType().Name);
????}
??}
結果:
????
State模式的幾個要點:
??? 1.State模式將所有一個特定狀態相關的行為都放入一個State的子類對象中,在對象狀態切換時,切換相應的對象;但同時維持State的接口,這樣實現了具體操作與狀態轉換之間的解耦。
??? 2.為不同的狀態引入不同的對象使得狀態轉換變得更加明確,而且可以保證不會出現狀態不一致的情況,因為轉換是原子性的----即要么徹底轉換過來,要么不轉換。
??? 3.如果State對象沒有實例變量,那么各個上下文可以共享 同一個State對象,從而節省對象開銷。
總結
以上是生活随笔為你收集整理的41状态模式(State Pattern)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 魅族19快充方案曝光:65W还是100W
- 下一篇: 异步、多线程、任务、并行编程之一:选择合