1+ //-------------------------------------------------------------------------------------
2+ // StateExample1.cs
3+ //-------------------------------------------------------------------------------------
4+
5+ using UnityEngine ;
6+ using System . Collections ;
7+
8+ //This real-world code demonstrates the State pattern which allows an Account to behave differently depending on its balance.
9+ //The difference in behavior is delegated to State objects called RedState, SilverState and GoldState.
10+ //These states represent overdrawn accounts, starter accounts, and accounts in good standing.
11+
12+ namespace StateExample1
13+ {
14+ public class StateExample1 : MonoBehaviour
15+ {
16+ void Start ( )
17+ {
18+ // Open a new account
19+ Account account = new Account ( "Jim Johnson" ) ;
20+
21+ // Apply financial transactions
22+ account . Deposit ( 500.0 ) ;
23+ account . Deposit ( 300.0 ) ;
24+ account . Deposit ( 550.0 ) ;
25+ account . PayInterest ( ) ;
26+ account . Withdraw ( 2000.00 ) ;
27+ account . Withdraw ( 1100.00 ) ;
28+ }
29+ }
30+
31+ /// <summary>
32+ /// The 'State' abstract class
33+ /// </summary>
34+ abstract class State
35+ {
36+ protected Account account ;
37+ protected double balance ;
38+
39+ protected double interest ;
40+ protected double lowerLimit ;
41+ protected double upperLimit ;
42+
43+ // Properties
44+ public Account Account
45+ {
46+ get { return account ; }
47+ set { account = value ; }
48+ }
49+
50+ public double Balance
51+ {
52+ get { return balance ; }
53+ set { balance = value ; }
54+ }
55+
56+ public abstract void Deposit ( double amount ) ;
57+ public abstract void Withdraw ( double amount ) ;
58+ public abstract void PayInterest ( ) ;
59+ }
60+
61+
62+ /// <summary>
63+ /// A 'ConcreteState' class
64+ /// <remarks>
65+ /// Red indicates that account is overdrawn
66+ /// </remarks>
67+ /// </summary>
68+ class RedState : State
69+ {
70+ private double _serviceFee ;
71+
72+ // Constructor
73+ public RedState ( State state )
74+ {
75+ this . balance = state . Balance ;
76+ this . account = state . Account ;
77+ Initialize ( ) ;
78+ }
79+
80+ private void Initialize ( )
81+ {
82+ // Should come from a datasource
83+ interest = 0.0 ;
84+ lowerLimit = - 100.0 ;
85+ upperLimit = 0.0 ;
86+ _serviceFee = 15.00 ;
87+ }
88+
89+ public override void Deposit ( double amount )
90+ {
91+ balance += amount ;
92+ StateChangeCheck ( ) ;
93+ }
94+
95+ public override void Withdraw ( double amount )
96+ {
97+ amount = amount - _serviceFee ;
98+ Debug . Log ( "No funds available for withdrawal!" ) ;
99+ }
100+
101+ public override void PayInterest ( )
102+ {
103+ // No interest is paid
104+ }
105+
106+ private void StateChangeCheck ( )
107+ {
108+ if ( balance > upperLimit )
109+ {
110+ account . State = new SilverState ( this ) ;
111+ }
112+ }
113+ }
114+
115+ /// <summary>
116+ /// A 'ConcreteState' class
117+ /// <remarks>
118+ /// Silver indicates a non-interest bearing state
119+ /// </remarks>
120+ /// </summary>
121+ class SilverState : State
122+ {
123+ // Overloaded constructors
124+
125+ public SilverState ( State state ) :
126+ this ( state . Balance , state . Account )
127+ {
128+ }
129+
130+ public SilverState ( double balance , Account account )
131+ {
132+ this . balance = balance ;
133+ this . account = account ;
134+ Initialize ( ) ;
135+ }
136+
137+ private void Initialize ( )
138+ {
139+ // Should come from a datasource
140+ interest = 0.0 ;
141+ lowerLimit = 0.0 ;
142+ upperLimit = 1000.0 ;
143+ }
144+
145+ public override void Deposit ( double amount )
146+ {
147+ balance += amount ;
148+ StateChangeCheck ( ) ;
149+ }
150+
151+ public override void Withdraw ( double amount )
152+ {
153+ balance -= amount ;
154+ StateChangeCheck ( ) ;
155+ }
156+
157+ public override void PayInterest ( )
158+ {
159+ balance += interest * balance ;
160+ StateChangeCheck ( ) ;
161+ }
162+
163+ private void StateChangeCheck ( )
164+ {
165+ if ( balance < lowerLimit )
166+ {
167+ account . State = new RedState ( this ) ;
168+ }
169+ else if ( balance > upperLimit )
170+ {
171+ account . State = new GoldState ( this ) ;
172+ }
173+ }
174+ }
175+
176+ /// <summary>
177+ /// A 'ConcreteState' class
178+ /// <remarks>
179+ /// Gold indicates an interest bearing state
180+ /// </remarks>
181+ /// </summary>
182+ class GoldState : State
183+ {
184+ // Overloaded constructors
185+ public GoldState ( State state )
186+ : this ( state . Balance , state . Account )
187+ {
188+ }
189+
190+ public GoldState ( double balance , Account account )
191+ {
192+ this . balance = balance ;
193+ this . account = account ;
194+ Initialize ( ) ;
195+ }
196+
197+ private void Initialize ( )
198+ {
199+ // Should come from a database
200+ interest = 0.05 ;
201+ lowerLimit = 1000.0 ;
202+ upperLimit = 10000000.0 ;
203+ }
204+
205+ public override void Deposit ( double amount )
206+ {
207+ balance += amount ;
208+ StateChangeCheck ( ) ;
209+ }
210+
211+ public override void Withdraw ( double amount )
212+ {
213+ balance -= amount ;
214+ StateChangeCheck ( ) ;
215+ }
216+
217+ public override void PayInterest ( )
218+ {
219+ balance += interest * balance ;
220+ StateChangeCheck ( ) ;
221+ }
222+
223+ private void StateChangeCheck ( )
224+ {
225+ if ( balance < 0.0 )
226+ {
227+ account . State = new RedState ( this ) ;
228+ }
229+ else if ( balance < lowerLimit )
230+ {
231+ account . State = new SilverState ( this ) ;
232+ }
233+ }
234+ }
235+
236+ /// <summary>
237+ /// The 'Context' class
238+ /// </summary>
239+ class Account
240+ {
241+ private State _state ;
242+ private string _owner ;
243+
244+ // Constructor
245+ public Account ( string owner )
246+ {
247+ // New accounts are 'Silver' by default
248+ this . _owner = owner ;
249+ this . _state = new SilverState ( 0.0 , this ) ;
250+ }
251+
252+ // Properties
253+ public double Balance
254+ {
255+ get { return _state . Balance ; }
256+ }
257+
258+ public State State
259+ {
260+ get { return _state ; }
261+ set { _state = value ; }
262+ }
263+
264+ public void Deposit ( double amount )
265+ {
266+ _state . Deposit ( amount ) ;
267+ Debug . Log ( "Deposited " + amount + "---" ) ;
268+ Debug . Log ( " Balance = " + this . Balance ) ;
269+ Debug . Log ( " Status = " + this . State . GetType ( ) . Name ) ;
270+ Debug . Log ( "" ) ;
271+ }
272+
273+ public void Withdraw ( double amount )
274+ {
275+ _state . Withdraw ( amount ) ;
276+ Debug . Log ( "Deposited " + amount + "---" ) ;
277+ Debug . Log ( " Balance = " + this . Balance ) ;
278+ Debug . Log ( " Status = " + this . State . GetType ( ) . Name + "\n " ) ;
279+ }
280+
281+ public void PayInterest ( )
282+ {
283+ _state . PayInterest ( ) ;
284+ Debug . Log ( "Interest Paid --- " ) ;
285+ Debug . Log ( " Balance = " + this . Balance ) ;
286+ Debug . Log ( " Status = " + this . State . GetType ( ) . Name ) ;
287+
288+ }
289+ }
290+ }
0 commit comments