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:
Petrutiu Mihai
2016-07-21 13:59:57 +03:00
parent 2bea7d280f
commit 1d04dafb70
5 changed files with 378 additions and 14 deletions

View File

@@ -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

View File

@@ -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()

View File

@@ -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
}
}

View File

@@ -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()