Skip to content

Commit 2b6ad35

Browse files
committed
Add Visitor pattern
1 parent e891643 commit 2b6ad35

8 files changed

+294
-8
lines changed

State/Account.cs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
3+
namespace DoFactory.GangOfFour.State.RealWorld
4+
{
5+
/// <summary>
6+
/// The 'Context' class
7+
/// </summary>
8+
public class Account
9+
{
10+
private State _state;
11+
private string _owner;
12+
13+
// Constructor
14+
public Account(string owner)
15+
{
16+
// New accounts are 'Silver' by default
17+
_owner = owner;
18+
_state = new SilverState(0.0, this);
19+
}
20+
21+
// Properties
22+
public double Balance => _state.Balance;
23+
24+
public State State { get => _state; set => _state = value; }
25+
26+
public void Deposit(double amount)
27+
{
28+
_state.Deposit(amount);
29+
Console.WriteLine("Deposited {0:C} --- ", amount);
30+
Console.WriteLine(" Balance = {0:C}", Balance);
31+
Console.WriteLine(" Status = {0}", State.GetType().Name);
32+
Console.WriteLine("");
33+
}
34+
35+
public void Withdraw(double amount)
36+
{
37+
_state.Withdraw(amount);
38+
Console.WriteLine("Withdrew {0:C} --- ", amount);
39+
Console.WriteLine(" Balance = {0:C}", Balance);
40+
Console.WriteLine(" Status = {0}\n", State.GetType().Name);
41+
}
42+
43+
public void PayInterest()
44+
{
45+
_state.PayInterest();
46+
Console.WriteLine("Interest Paid --- ");
47+
Console.WriteLine(" Balance = {0:C}", Balance);
48+
Console.WriteLine(" Status = {0}\n", State.GetType().Name);
49+
}
50+
}
51+
}

State/Program.cs

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
7-
namespace State
2+
namespace DoFactory.GangOfFour.State.RealWorld
83
{
9-
class Program
4+
/// <summary>
5+
/// MainApp startup class for Real-World
6+
/// State Design Pattern.
7+
/// </summary>
8+
class MainApp
109
{
11-
static void Main(string[] args)
10+
/// <summary>
11+
/// Entry point into console application.
12+
/// </summary>
13+
static void Main()
1214
{
15+
// Open a new account
16+
Account account = new Account("Jim Johnson");
17+
// Apply financial transactions
18+
account.Deposit(500.0);
19+
account.Deposit(300.0);
20+
account.Deposit(550.0);
21+
account.PayInterest();
22+
account.Withdraw(2000.00);
23+
account.Withdraw(1100.00);
24+
// Wait for user
25+
Console.ReadKey();
1326
}
1427
}
1528
}

State/State.cs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace DoFactory.GangOfFour.State.RealWorld
2+
{
3+
/// <summary>
4+
/// The 'State' abstract class
5+
/// </summary>
6+
public abstract class State
7+
{
8+
protected Account account;
9+
protected double balance;
10+
protected double interest;
11+
protected double lowerLimit;
12+
protected double upperLimit;
13+
14+
// Properties
15+
public Account Account
16+
{
17+
get { return account; }
18+
set { account = value; }
19+
}
20+
21+
public double Balance
22+
{
23+
get { return balance; }
24+
set { balance = value; }
25+
}
26+
27+
public abstract void Deposit(double amount);
28+
29+
public abstract void Withdraw(double amount);
30+
31+
public abstract void PayInterest();
32+
33+
}
34+
}

State/State.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@
4242
<Reference Include="System.Xml" />
4343
</ItemGroup>
4444
<ItemGroup>
45+
<Compile Include="Account.cs" />
46+
<Compile Include="GoldState.cs" />
4547
<Compile Include="Program.cs" />
4648
<Compile Include="Properties\AssemblyInfo.cs" />
49+
<Compile Include="RedState.cs" />
50+
<Compile Include="SilverState.cs" />
51+
<Compile Include="State.cs" />
4752
</ItemGroup>
4853
<ItemGroup>
4954
<None Include="App.config" />

State/States/GoldState.cs

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
namespace DoFactory.GangOfFour.State.RealWorld
2+
{
3+
/// <summary>
4+
/// A 'ConcreteState' class
5+
/// <remarks>
6+
/// Gold indicates an interest bearing state
7+
/// </remarks>
8+
/// </summary>
9+
public class GoldState : State
10+
{
11+
// Overloaded constructors
12+
public GoldState(State state)
13+
: this(state.Balance, state.Account)
14+
{
15+
}
16+
17+
public GoldState(double balance, Account account)
18+
{
19+
this.balance = balance;
20+
this.account = account;
21+
Initialize();
22+
}
23+
24+
private void Initialize()
25+
{
26+
// Should come from a database
27+
interest = 0.05;
28+
lowerLimit = 1000.0;
29+
upperLimit = 10000000.0;
30+
}
31+
32+
public override void Deposit(double amount)
33+
{
34+
balance += amount;
35+
StateChangeCheck();
36+
}
37+
38+
public override void Withdraw(double amount)
39+
{
40+
balance -= amount;
41+
StateChangeCheck();
42+
}
43+
44+
public override void PayInterest()
45+
{
46+
balance += interest * balance;
47+
StateChangeCheck();
48+
}
49+
50+
private void StateChangeCheck()
51+
{
52+
if (balance < 0.0)
53+
{
54+
account.State = new RedState(this);
55+
}
56+
else if (balance < lowerLimit)
57+
{
58+
account.State = new SilverState(this);
59+
}
60+
}
61+
}
62+
}

State/States/RedState.cs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
3+
namespace DoFactory.GangOfFour.State.RealWorld
4+
{
5+
/// <summary>
6+
/// A 'ConcreteState' class
7+
/// <remarks>
8+
/// Red indicates that account is overdrawn
9+
/// </remarks>
10+
/// </summary>
11+
public class RedState : State
12+
{
13+
private double _serviceFee;
14+
// Constructor
15+
public RedState(State state)
16+
{
17+
balance = state.Balance;
18+
account = state.Account;
19+
Initialize();
20+
21+
}
22+
23+
private void Initialize()
24+
{
25+
// Should come from a datasource
26+
interest = 0.0;
27+
lowerLimit = -100.0;
28+
upperLimit = 0.0;
29+
_serviceFee = 15.00;
30+
}
31+
32+
public override void Deposit(double amount)
33+
{
34+
balance += amount;
35+
StateChangeCheck();
36+
}
37+
38+
public override void Withdraw(double amount)
39+
{
40+
amount -= _serviceFee;
41+
Console.WriteLine("No funds available for withdrawal!");
42+
}
43+
44+
public override void PayInterest()
45+
{
46+
// No interest is paid
47+
}
48+
49+
private void StateChangeCheck()
50+
{
51+
if (balance > upperLimit)
52+
{
53+
account.State = new SilverState(this);
54+
}
55+
}
56+
}
57+
}

State/States/SilverState.cs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
namespace DoFactory.GangOfFour.State.RealWorld
2+
{
3+
/// <summary>
4+
/// A 'ConcreteState' class
5+
/// <remarks>
6+
/// Silver indicates a non-interest bearing state
7+
/// </remarks>
8+
/// </summary>
9+
public class SilverState : State
10+
{
11+
// Overloaded constructors
12+
public SilverState(State state) :
13+
this(state.Balance, state.Account)
14+
{
15+
}
16+
17+
public SilverState(double balance, Account account)
18+
{
19+
this.balance = balance;
20+
this.account = account;
21+
Initialize();
22+
}
23+
24+
private void Initialize()
25+
{
26+
// Should come from a datasource
27+
interest = 0.0;
28+
lowerLimit = 0.0;
29+
upperLimit = 1000.0;
30+
}
31+
32+
public override void Deposit(double amount)
33+
{
34+
balance += amount;
35+
StateChangeCheck();
36+
}
37+
38+
public override void Withdraw(double amount)
39+
{
40+
balance -= amount;
41+
StateChangeCheck();
42+
}
43+
44+
public override void PayInterest()
45+
{
46+
balance += interest * balance;
47+
StateChangeCheck();
48+
}
49+
50+
private void StateChangeCheck()
51+
{
52+
// account.State = balance < lowerLimit ? new RedState(this) : new GoldState(this);
53+
if (balance < lowerLimit)
54+
{
55+
account.State = new RedState(this);
56+
}
57+
else
58+
{
59+
account.State = new GoldState(this);
60+
}
61+
}
62+
63+
}
64+
}

State/state.gif

4.66 KB
Loading

0 commit comments

Comments
 (0)