Skip to content

Commit 25d3a5c

Browse files
committed
Added State Pattern
1 parent 7a934ee commit 25d3a5c

24 files changed

Lines changed: 811 additions & 24 deletions

‎src/SoftwarePatterns.Core/PatternList.txt‎

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ Factory method:
1010
Define an interface for creating a single object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
1111
Lazy Loading
1212
Tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.
13-
13+
Prototype
14+
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
15+
Singleton
16+
Ensure a class has only one instance, and provide a global point of access to it.
1417

1518
Structural patterns:
1619

@@ -20,31 +23,33 @@ Bridge
2023
Decouple an abstraction from its implementation allowing the two to vary independently.
2124
Composite
2225
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
23-
Decorator:
26+
Decorator
2427
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to sub classing for extending functionality.
25-
Facade:
28+
Facade
2629
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
27-
Flyweight:
30+
Flyweight
2831
Use sharing to support large numbers of similar objects efficiently.
29-
Proxy:
32+
Proxy
3033
Provide a surrogate or placeholder for another object to control access to it. (Also used in lazy loading)
3134

3235

3336
Behavioural patterns:
3437

35-
Chain of responsibility:
38+
Chain of responsibility
3639
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
37-
Command:
40+
Command
3841
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
39-
Interpreter:
42+
Interpreter
4043
Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
41-
Iterator:
44+
Iterator
4245
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
43-
Mediator:
46+
Mediator
4447
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
45-
Memento:
48+
Memento
4649
Without violating encapsulation, capture and externalize an object's internal state allowing the object to be restored to this state later. Yes No N/A
47-
Null object:
50+
Null object
4851
Avoid null references by providing a default object.
49-
Observer or Publish/subscribe:
50-
Define a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically.
52+
Observer or Publish/subscribe
53+
Define a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically.
54+
State
55+
Allow an object to alter its behaviour when its internal state changes. The object will appear to change its class.

‎src/SoftwarePatterns.Core/SoftwarePatterns.Core.csproj‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@
180180
<Compile Include="ServiceLocator\Locator.cs" />
181181
<Compile Include="ServiceLocator\PackageProcessor.cs" />
182182
<Compile Include="Singleton\Singleton.cs" />
183+
<Compile Include="State\ActiveState.cs" />
184+
<Compile Include="State\BaseState.cs" />
185+
<Compile Include="State\ClosedState.cs" />
186+
<Compile Include="State\ICommands.cs" />
187+
<Compile Include="State\ProposedState.cs" />
188+
<Compile Include="State\ResolvedState.cs" />
189+
<Compile Include="State\Status.cs" />
190+
<Compile Include="State\WorkItem.cs" />
191+
<Compile Include="State\WorkItemContainer.cs" />
183192
<Compile Include="UnitOfWork\IRepositoryProvider.cs" />
184193
<Compile Include="UnitOfWork\IUnitOfWork.cs" />
185194
<Compile Include="UnitOfWork\RepositoryFactories.cs" />
@@ -212,6 +221,7 @@
212221
<Content Include="Repository\ReadMe.txt" />
213222
<Content Include="ServiceLocator\ReadMe.txt" />
214223
<Content Include="Singleton\ReadMe.txt" />
224+
<Content Include="State\ReadMe.txt" />
215225
<Content Include="UnitOfWork\ReadMe.txt" />
216226
</ItemGroup>
217227
<ItemGroup>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
3+
namespace SoftwarePatterns.Core.State
4+
{
5+
public class ActiveState : BaseState
6+
{
7+
public ActiveState(WorkItem owner) :base(owner) { }
8+
9+
public override bool Delete()
10+
{
11+
Console.WriteLine("Work item is already active, can't be deleted");
12+
return false;
13+
}
14+
15+
public override void Edit(string name, string description)
16+
{
17+
_owner.Name = name;
18+
_owner.Description = description;
19+
}
20+
21+
public override void SetState(Status newState)
22+
{
23+
switch (newState)
24+
{
25+
case Status.Active:
26+
Console.WriteLine("Work item is already active");
27+
break;
28+
case Status.Proposed:
29+
case Status.Resolved:
30+
_owner.State = newState;
31+
break;
32+
case Status.Closed:
33+
Console.WriteLine("Work item is in active state and can't be closed");
34+
break;
35+
}
36+
}
37+
}
38+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
3+
namespace SoftwarePatterns.Core.State
4+
{
5+
public abstract class BaseState : ICommands
6+
{
7+
protected readonly WorkItem _owner;
8+
9+
protected BaseState(WorkItem owner)
10+
{
11+
_owner = owner;
12+
}
13+
14+
public abstract bool Delete();
15+
16+
public abstract void Edit(string name, string description);
17+
18+
public virtual void Print()
19+
{
20+
Console.WriteLine();
21+
Console.WriteLine("WorkItem ID: {0}", _owner.Id);
22+
Console.WriteLine("WorkItem Name: {0}", _owner.Name);
23+
Console.WriteLine("WorkItem State: {0}", _owner.State);
24+
Console.WriteLine("WorkItem Description: {0}", _owner.Description);
25+
Console.WriteLine();
26+
}
27+
28+
public abstract void SetState(Status newState);
29+
}
30+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
3+
namespace SoftwarePatterns.Core.State
4+
{
5+
public class ClosedState : BaseState
6+
{
7+
public ClosedState(WorkItem owner) : base(owner)
8+
{
9+
}
10+
11+
public override bool Delete()
12+
{
13+
return true;
14+
}
15+
16+
public override void Edit(string name, string description)
17+
{
18+
Console.WriteLine("Can't edit a closed work item");
19+
}
20+
21+
public override void SetState(Status newState)
22+
{
23+
switch (newState)
24+
{
25+
case Status.Proposed:
26+
Console.WriteLine("Work item is already closed it can't be set to Proposed");
27+
break;
28+
case Status.Active:
29+
Console.WriteLine("Work item is already closed it can't be set to Active");
30+
break;
31+
case Status.Resolved:
32+
_owner.State = newState;
33+
break;
34+
case Status.Closed:
35+
Console.WriteLine("Work item is already closed");
36+
break;
37+
}
38+
}
39+
}
40+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SoftwarePatterns.Core.State
2+
{
3+
public interface ICommands
4+
{
5+
bool Delete();
6+
void Edit(string name, string description);
7+
void Print();
8+
void SetState(Status newState);
9+
}
10+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
3+
namespace SoftwarePatterns.Core.State
4+
{
5+
public class ProposedState : BaseState
6+
{
7+
public ProposedState(WorkItem owner) : base(owner)
8+
{
9+
}
10+
11+
public override bool Delete()
12+
{
13+
Console.WriteLine("Work item is not yet active it can be deleted");
14+
return true;
15+
}
16+
17+
public override void Edit(string name, string description)
18+
{
19+
_owner.Name = name;
20+
_owner.Description = description;
21+
}
22+
23+
public override void SetState(Status newState)
24+
{
25+
switch (newState)
26+
{
27+
case Status.Active:
28+
_owner.State = newState;
29+
break;
30+
case Status.Proposed:
31+
Console.WriteLine("Work item is already Proposed");
32+
break;
33+
case Status.Resolved:
34+
Console.WriteLine("Work item is not yet active it can't be resolved");
35+
break;
36+
case Status.Closed:
37+
Console.WriteLine("Work item is not yet active it can't be closed");
38+
break;
39+
}
40+
}
41+
}
42+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Define:
2+
The state pattern, which closely resembles Strategy Pattern, is a behavioural software design pattern, also known as the objects for states pattern.
3+
4+
Usage:
5+
When the behaviour of an object needs to change based on its internal state
6+
7+
Intent:
8+
Change behaviour of object with each state
9+
Encapsulate the logic of each state into a single object
10+
Allow for dynamic state discovery
11+
Make unit testing easier
12+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
3+
namespace SoftwarePatterns.Core.State
4+
{
5+
public class ResolvedState : BaseState
6+
{
7+
public ResolvedState(WorkItem owner) : base(owner)
8+
{
9+
}
10+
11+
public override bool Delete()
12+
{
13+
Console.WriteLine("Work item is already active, can't be deleted");
14+
return false;
15+
}
16+
17+
public override void Edit(string name, string description)
18+
{
19+
_owner.Name = name;
20+
_owner.Description = description;
21+
}
22+
23+
public override void SetState(Status newState)
24+
{
25+
switch (newState)
26+
{
27+
case Status.Proposed:
28+
Console.WriteLine("Work item is already resolved it can't be set to Proposed");
29+
break;
30+
case Status.Active:
31+
_owner.State = newState;
32+
break;
33+
case Status.Resolved:
34+
Console.WriteLine("Work item is already resolved");
35+
break;
36+
case Status.Closed:
37+
_owner.State = newState;
38+
break;
39+
}
40+
}
41+
}
42+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SoftwarePatterns.Core.State
2+
{
3+
public enum Status
4+
{
5+
Proposed,
6+
Active,
7+
Resolved,
8+
Closed
9+
}
10+
}

0 commit comments

Comments
 (0)