Add BehavioralPatterns project back again in the solution (somehow it was gone)
Update Scrum example on State pattern Add Scrum pattern using state role interfaces
This commit is contained in:
@@ -31,6 +31,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TemplatePattern", "src\Temp
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "VisitorPattern", "src\VisitorPattern\VisitorPattern.xproj", "{CDDB889F-3038-4796-95B1-47E1834DA93D}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BehavioralPatterns", "src\BehavioralPatterns\BehavioralPatterns.xproj", "{E3092EE0-1282-4AB4-9FA2-0338348D8FD1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -77,6 +79,10 @@ Global
|
||||
{CDDB889F-3038-4796-95B1-47E1834DA93D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CDDB889F-3038-4796-95B1-47E1834DA93D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CDDB889F-3038-4796-95B1-47E1834DA93D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E3092EE0-1282-4AB4-9FA2-0338348D8FD1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -92,5 +98,6 @@ Global
|
||||
{01B9D869-AF89-4919-8445-79206848FB5F} = {3820200F-354C-41E6-8F34-B301F5D621C2}
|
||||
{E657BF85-C23A-46DE-B837-6939D51C3321} = {3820200F-354C-41E6-8F34-B301F5D621C2}
|
||||
{CDDB889F-3038-4796-95B1-47E1834DA93D} = {3820200F-354C-41E6-8F34-B301F5D621C2}
|
||||
{E3092EE0-1282-4AB4-9FA2-0338348D8FD1} = {3820200F-354C-41E6-8F34-B301F5D621C2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace StatePattern.ScrumExample
|
||||
/// User story states: New, Active, Resolved, Closed, Removed
|
||||
/// Actions on user stories:
|
||||
/// Create - creates a new user story in state New
|
||||
/// RemoveFromBacklog - moves a user story from state New to State removed
|
||||
/// RemoveFromBacklog - moves a user story from state New to State Removed
|
||||
/// StartImplementation - moves user story from state New to state Active
|
||||
/// MoveToBacklog - moves user story from state Active/Removed to state New
|
||||
/// CodeFinishedAnUnitTestsPassed - move user story from state Active to state Resolved
|
||||
|
||||
@@ -25,10 +25,13 @@ namespace StatePattern.ScrumExample
|
||||
//but leaving that asside, assuming we will have to add another transition availalable that can be executed only from one state
|
||||
//we will have to modify all the existing states, just to throw the exception.
|
||||
|
||||
|
||||
//To view what are the allowed transitions, is very hard when using state pattern with roles
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State interface
|
||||
/// </summary>
|
||||
public interface IScrumState
|
||||
{
|
||||
void RemoveFromBacklog();
|
||||
@@ -41,11 +44,25 @@ namespace StatePattern.ScrumExample
|
||||
|
||||
void AcceptanceTestsPassed();
|
||||
|
||||
void CodeFinishedAnUnitTestsPassed();
|
||||
void CodeFinishedAndUnitTestsPassed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context
|
||||
/// User story states: New, Active, Resolved, Closed, Removed
|
||||
/// Actions on user stories:
|
||||
/// Create - creates a new user story in state New
|
||||
/// RemoveFromBacklog - moves a user story from state New to State removed
|
||||
/// StartImplementation - moves user story from state New to state Active
|
||||
/// MoveToBacklog - moves user story from state Active/Removed to state New
|
||||
/// CodeFinishedAndUnitTestsPassed - move user story from state Active to state Resolved
|
||||
/// AcceptanceTestsFail - move user story from state Resolved to state Active
|
||||
/// AcceptanceTestsPassed - moves user story from state Resolved to state Closed
|
||||
/// </summary>
|
||||
public class UserStory
|
||||
{
|
||||
public IScrumState State { get; set; }
|
||||
|
||||
public IScrumState New { get; private set; }
|
||||
public IScrumState Active { get; private set; }
|
||||
public IScrumState Resolved { get; private set; }
|
||||
@@ -62,7 +79,6 @@ namespace StatePattern.ScrumExample
|
||||
|
||||
State = New;
|
||||
}
|
||||
public IScrumState State { get; set; }
|
||||
public int Name { get; internal set; }
|
||||
|
||||
public void AcceptanceTestsFail()
|
||||
@@ -89,12 +105,15 @@ namespace StatePattern.ScrumExample
|
||||
State.StartImplementation();
|
||||
}
|
||||
|
||||
public void CodeFinishedAnUnitTestsPassed()
|
||||
public void CodeFinishedAndUnitTestsPassed()
|
||||
{
|
||||
State.CodeFinishedAnUnitTestsPassed();
|
||||
State.CodeFinishedAndUnitTestsPassed();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Concrete State
|
||||
/// </summary>
|
||||
internal class ScrumStateNew : IScrumState
|
||||
{
|
||||
private UserStory userStory;
|
||||
@@ -116,7 +135,7 @@ namespace StatePattern.ScrumExample
|
||||
Console.WriteLine("Development didn't even started, you should check your tests");
|
||||
}
|
||||
|
||||
public void CodeFinishedAnUnitTestsPassed()
|
||||
public void CodeFinishedAndUnitTestsPassed()
|
||||
{
|
||||
//throw the exception
|
||||
Console.WriteLine("Before you can finish the code, you should have started implementation");
|
||||
@@ -130,8 +149,8 @@ namespace StatePattern.ScrumExample
|
||||
|
||||
public void RemoveFromBacklog()
|
||||
{
|
||||
//throw the exception
|
||||
Console.WriteLine("User story removed");
|
||||
userStory.State = userStory.Removed;
|
||||
}
|
||||
|
||||
public void StartImplementation()
|
||||
@@ -141,6 +160,9 @@ namespace StatePattern.ScrumExample
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Concrete State
|
||||
/// </summary>
|
||||
internal class ScrumStateActive : IScrumState
|
||||
{
|
||||
private UserStory userStory;
|
||||
@@ -162,7 +184,7 @@ namespace StatePattern.ScrumExample
|
||||
Console.WriteLine("Development is not yet done");
|
||||
}
|
||||
|
||||
public void CodeFinishedAnUnitTestsPassed()
|
||||
public void CodeFinishedAndUnitTestsPassed()
|
||||
{
|
||||
Console.WriteLine("I'll notify the testers!");
|
||||
userStory.State = userStory.Resolved;
|
||||
@@ -170,8 +192,8 @@ namespace StatePattern.ScrumExample
|
||||
|
||||
public void MoveToBacklog()
|
||||
{
|
||||
//throw the exception
|
||||
Console.WriteLine("Moved userstory to backlog");
|
||||
userStory.State = userStory.New;
|
||||
}
|
||||
|
||||
public void RemoveFromBacklog()
|
||||
@@ -187,6 +209,9 @@ namespace StatePattern.ScrumExample
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Concrete State
|
||||
/// </summary>
|
||||
internal class ScrumStateResolved : IScrumState
|
||||
{
|
||||
private UserStory userStory;
|
||||
@@ -208,7 +233,7 @@ namespace StatePattern.ScrumExample
|
||||
userStory.State = userStory.Closed;
|
||||
}
|
||||
|
||||
public void CodeFinishedAnUnitTestsPassed()
|
||||
public void CodeFinishedAndUnitTestsPassed()
|
||||
{
|
||||
//throw the exception
|
||||
Console.WriteLine("The item was already resolved");
|
||||
@@ -233,6 +258,9 @@ namespace StatePattern.ScrumExample
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Concrete State
|
||||
/// </summary>
|
||||
internal class ScrumStateClosed : IScrumState
|
||||
{
|
||||
private UserStory userStory;
|
||||
@@ -254,7 +282,7 @@ namespace StatePattern.ScrumExample
|
||||
Console.WriteLine("User story is already closed");
|
||||
}
|
||||
|
||||
public void CodeFinishedAnUnitTestsPassed()
|
||||
public void CodeFinishedAndUnitTestsPassed()
|
||||
{
|
||||
//throw the exception
|
||||
Console.WriteLine("Item was already closed");
|
||||
@@ -262,6 +290,7 @@ namespace StatePattern.ScrumExample
|
||||
|
||||
public void MoveToBacklog()
|
||||
{
|
||||
//throw the exception
|
||||
Console.WriteLine("Item was already closed, cannot move to new state");
|
||||
}
|
||||
|
||||
@@ -278,6 +307,9 @@ namespace StatePattern.ScrumExample
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Concrete State
|
||||
/// </summary>
|
||||
internal class ScrumStateRemoved : IScrumState
|
||||
{
|
||||
private UserStory userStory;
|
||||
@@ -299,9 +331,9 @@ namespace StatePattern.ScrumExample
|
||||
Console.WriteLine("Item was removed, you can only move it to backlog again");
|
||||
}
|
||||
|
||||
public void CodeFinishedAnUnitTestsPassed()
|
||||
public void CodeFinishedAndUnitTestsPassed()
|
||||
{
|
||||
|
||||
//throw the exception
|
||||
}
|
||||
|
||||
public void MoveToBacklog()
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
|
||||
namespace StatePattern.ScrumWithRoleStates
|
||||
{
|
||||
public class ScrumStateWithRoleInterfacesExample
|
||||
{
|
||||
public static void Run()
|
||||
{
|
||||
UserStory userStory = new UserStory();
|
||||
userStory.RemoveFromBacklog();
|
||||
userStory.MoveToBacklog();
|
||||
userStory.StartImplementation();
|
||||
userStory.AcceptanceTestsFail();
|
||||
userStory.StartImplementation();
|
||||
userStory.AcceptanceTestsPassed();
|
||||
userStory.StartImplementation();
|
||||
|
||||
userStory.CodeFinishedAnUnitTestsPassed();
|
||||
|
||||
userStory.AcceptanceTestsPassed();
|
||||
|
||||
Console.WriteLine("User story state: {0}", userStory.State.Name);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context
|
||||
/// User story states: New, Active, Resolved, Closed, Removed
|
||||
/// Actions on user stories:
|
||||
/// Create - creates a new user story in state New
|
||||
/// RemoveFromBacklog - moves a user story from state New to State Removed
|
||||
/// StartImplementation - moves user story from state New to state Active
|
||||
/// MoveToBacklog - moves user story from state Active/Removed to state New
|
||||
/// CodeFinishedAndUnitTestsPassed - move user story from state Active to state Resolved
|
||||
/// AcceptanceTestsFail - move user story from state Resolved to state Active
|
||||
/// AcceptanceTestsPassed - moves user story from state Resolved to state Closed
|
||||
/// </summary>
|
||||
public class UserStory
|
||||
{
|
||||
public IScrumState State { get; set; }
|
||||
|
||||
public UserStoryStates States { get; private set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public UserStory()
|
||||
{
|
||||
States = new UserStoryStates(this);
|
||||
|
||||
State = States.New;
|
||||
}
|
||||
|
||||
public void MoveToBacklog()
|
||||
{
|
||||
ICanMoveToBacklog state = GetState<ICanMoveToBacklog>();
|
||||
|
||||
if(state == null)
|
||||
{
|
||||
Console.WriteLine("Cannot move to backlog from state: {0}", State.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
state.MoveToBacklog();
|
||||
}
|
||||
|
||||
public void StartImplementation()
|
||||
{
|
||||
ICanStartImplementation state = GetState<ICanStartImplementation>();
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
Console.WriteLine("Cannot start implementation from state: {0}", State.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
state.StartImplementation();
|
||||
}
|
||||
|
||||
public void CodeFinishedAnUnitTestsPassed()
|
||||
{
|
||||
ICanFinishCode state = GetState<ICanFinishCode>();
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
Console.WriteLine("Cannot mark the code as done from state: {0}", State.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
state.CodeFinishedAndUnitTestsPassed();
|
||||
}
|
||||
|
||||
public void AcceptanceTestsFail()
|
||||
{
|
||||
ICanRunAcceptanceTests state = GetState<ICanRunAcceptanceTests>();
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
Console.WriteLine("Cannot fail the acceptance tests from state: {0}", State.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
state.AcceptanceTestsFail();
|
||||
}
|
||||
|
||||
public void AcceptanceTestsPassed()
|
||||
{
|
||||
ICanRunAcceptanceTests state = GetState<ICanRunAcceptanceTests>();
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
Console.WriteLine("Cannot mark the code as done from state: {0}", State.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
state.AcceptanceTestsPassed();
|
||||
}
|
||||
|
||||
public void RemoveFromBacklog()
|
||||
{
|
||||
ICanRemoveFromBacklog state = GetState<ICanRemoveFromBacklog>();
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
Console.WriteLine("Cannot remove from backlog from state: {0}", State.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
state.RemoveFromBacklog();
|
||||
}
|
||||
|
||||
private TTransition GetState<TTransition>()
|
||||
{
|
||||
if(State is TTransition)
|
||||
{
|
||||
return (TTransition)State;
|
||||
}
|
||||
|
||||
return default(TTransition);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State interface
|
||||
/// </summary>
|
||||
public interface IScrumState
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
|
||||
public class UserStoryStates
|
||||
{
|
||||
public UserStoryStates(UserStory userStory)
|
||||
{
|
||||
New = new ScrumStateNew(userStory);
|
||||
Active = new ScrumStateActive(userStory);
|
||||
Resolved = new ScrumStateResolved(userStory);
|
||||
Closed = new ScrumStateClosed(userStory);
|
||||
Removed = new ScrumStateRemoved(userStory);
|
||||
|
||||
|
||||
//Defined but not used, we could use this array to get from what state we can do an operation, by just checking which implements the required interface
|
||||
AllStates = new IScrumState[] { New, Active, Resolved, Closed, Removed };
|
||||
}
|
||||
public IScrumState[] AllStates { get; private set; }
|
||||
|
||||
public IScrumState New { get; private set; }
|
||||
|
||||
public IScrumState Active { get; private set; }
|
||||
|
||||
public IScrumState Resolved { get; private set; }
|
||||
|
||||
public IScrumState Closed { get; private set; }
|
||||
|
||||
public IScrumState Removed { get; private set; }
|
||||
}
|
||||
|
||||
|
||||
#region role interfaces
|
||||
internal interface ICanMoveToBacklog
|
||||
{
|
||||
void MoveToBacklog();
|
||||
}
|
||||
|
||||
|
||||
internal interface ICanStartImplementation
|
||||
{
|
||||
void StartImplementation();
|
||||
}
|
||||
|
||||
internal interface ICanFinishCode
|
||||
{
|
||||
void CodeFinishedAndUnitTestsPassed();
|
||||
}
|
||||
|
||||
internal interface ICanRunAcceptanceTests
|
||||
{
|
||||
void AcceptanceTestsFail();
|
||||
|
||||
void AcceptanceTestsPassed();
|
||||
}
|
||||
|
||||
internal interface ICanRemoveFromBacklog
|
||||
{
|
||||
void RemoveFromBacklog();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region concrete state implementations
|
||||
public class ScrumStateNew : IScrumState, ICanRemoveFromBacklog, ICanStartImplementation
|
||||
{
|
||||
private UserStory userStory;
|
||||
|
||||
public ScrumStateNew(UserStory userStory)
|
||||
{
|
||||
this.userStory = userStory;
|
||||
}
|
||||
|
||||
public string Name { get { return "New"; } }
|
||||
|
||||
public void RemoveFromBacklog()
|
||||
{
|
||||
Console.WriteLine("User story removed");
|
||||
userStory.State = userStory.States.Removed;
|
||||
}
|
||||
|
||||
public void StartImplementation()
|
||||
{
|
||||
Console.WriteLine("Started work on User story: {0}", userStory.Name);
|
||||
userStory.State = userStory.States.Active;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScrumStateRemoved : IScrumState, ICanMoveToBacklog
|
||||
{
|
||||
private UserStory userStory;
|
||||
|
||||
public ScrumStateRemoved(UserStory userStory)
|
||||
{
|
||||
this.userStory = userStory;
|
||||
}
|
||||
|
||||
public string Name { get { return "Removed"; } }
|
||||
|
||||
public void MoveToBacklog()
|
||||
{
|
||||
Console.WriteLine("Moved userstory to backlog");
|
||||
userStory.State = userStory.States.New;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScrumStateActive : IScrumState, ICanMoveToBacklog, ICanFinishCode
|
||||
{
|
||||
private UserStory userStory;
|
||||
|
||||
public ScrumStateActive(UserStory userStory)
|
||||
{
|
||||
this.userStory = userStory;
|
||||
}
|
||||
|
||||
public string Name { get { return "Active"; } }
|
||||
|
||||
public void CodeFinishedAndUnitTestsPassed()
|
||||
{
|
||||
Console.WriteLine("I'll notify the testers!");
|
||||
userStory.State = userStory.States.Resolved;
|
||||
}
|
||||
|
||||
public void MoveToBacklog()
|
||||
{
|
||||
Console.WriteLine("Moved userstory to backlog");
|
||||
userStory.State = userStory.States.New;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScrumStateResolved : IScrumState, ICanRunAcceptanceTests
|
||||
{
|
||||
private UserStory userStory;
|
||||
|
||||
public ScrumStateResolved(UserStory userStory)
|
||||
{
|
||||
this.userStory = userStory;
|
||||
}
|
||||
|
||||
public string Name { get { return "Resolved"; } }
|
||||
|
||||
public void AcceptanceTestsFail()
|
||||
{
|
||||
Console.WriteLine("We'll notify the devs, that they did a bad job");
|
||||
userStory.State = userStory.States.Active;
|
||||
}
|
||||
|
||||
public void AcceptanceTestsPassed()
|
||||
{
|
||||
Console.WriteLine("Cool, we'll close the us");
|
||||
userStory.State = userStory.States.Closed;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScrumStateClosed : IScrumState
|
||||
{
|
||||
private UserStory userStory;
|
||||
|
||||
public ScrumStateClosed(UserStory userStory)
|
||||
{
|
||||
this.userStory = userStory;
|
||||
}
|
||||
|
||||
public string Name { get { return "Closed"; } }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using StatePattern.FanExample;
|
||||
using StatePattern.ScrumExample;
|
||||
using StatePattern.ScrumWithRoleStates;
|
||||
using StatePattern.TVExample;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -32,6 +33,9 @@ namespace StatePattern
|
||||
|
||||
GoToNextStep();
|
||||
ScrumStatePatternExample.Run();
|
||||
|
||||
GoToNextStep();
|
||||
ScrumStateWithRoleInterfacesExample.Run();
|
||||
}
|
||||
|
||||
private static void GoToNextStep()
|
||||
|
||||
Reference in New Issue
Block a user