diff --git a/src/StatePattern/ScrumExample/ScrumMotivationalExample.cs b/src/StatePattern/ScrumExample/ScrumMotivationalExample.cs new file mode 100644 index 0000000..1959f9e --- /dev/null +++ b/src/StatePattern/ScrumExample/ScrumMotivationalExample.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace StatePattern.ScrumExample +{ + public class ScrumMotivationalExample + { + public static void Run() + { + ScrumMotivationalContext context = new ScrumMotivationalContext(); + + UserStoryMotivational userStory = new UserStoryMotivational(); + context.Create(userStory); + context.RemoveFromBacklog(userStory); + context.MoveToBacklog(userStory); + context.StartImplementation(userStory); + context.AcceptanceTestsFail(userStory); + context.StartImplementation(userStory); + context.AcceptanceTestsPassed(userStory); + + context.StartImplementation(userStory); + } + } + + /// + /// 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 + /// CodeFinishedAnUnitTestsPassed - 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 + /// + public class ScrumMotivationalContext + { + + public void Create(UserStoryMotivational userStory) + { + userStory.State = UserStoryState.New; + } + + public void RemoveFromBacklog(UserStoryMotivational userStory) + { + switch (userStory.State) + { + case UserStoryState.New: + Console.WriteLine("User story removed"); + userStory.State = UserStoryState.Removed; + break; + case UserStoryState.Removed: + Console.WriteLine("Already in removed state"); + break; + case UserStoryState.Closed: + Console.WriteLine("Once a User Story is Closed, it cannot be removed"); + break; + case UserStoryState.Resolved: + Console.WriteLine(@"The item was already resolved, it can be deleted only if the acceptance tests failed and moved to backlog"); + break; + case UserStoryState.Active: + Console.WriteLine("You must first move the item to backlog"); + break; + default: + throw new Exception(string.Format("Cannot process user stories that are in {0} state", userStory.State)); + } + } + + public void StartImplementation(UserStoryMotivational userStory) + { + switch (userStory.State) + { + case UserStoryState.New: + Console.WriteLine("Started work on User story: {0}", userStory.Name); + userStory.State = UserStoryState.Active; + break; + case UserStoryState.Removed: + case UserStoryState.Active: + case UserStoryState.Resolved: + case UserStoryState.Closed: + Console.WriteLine("You can start work only on user stories that are new, current user story state is: {0}", userStory.State); + break; + default: + throw new Exception(string.Format("Cannot process user stories that are in {0} state", userStory.State)); + } + } + + public void MoveToBacklog(UserStoryMotivational userStory) + { + switch (userStory.State) + { + case UserStoryState.New: + Console.WriteLine("Already in backlog"); + break; + case UserStoryState.Removed: + case UserStoryState.Active: + Console.WriteLine("Moved userstory to backlog"); + userStory.State = UserStoryState.New; + break; + case UserStoryState.Resolved: + Console.WriteLine("Item was already resolved, it can be moved to backlog, only if the acceptance tests failed"); + break; + case UserStoryState.Closed: + Console.WriteLine("Item was already closed, cannot move to new state"); + break; + default: + throw new Exception(string.Format("Cannot process user stories that are in {0} state", userStory.State)); + } + } + + public void CodeFinishedAnUnitTestsPassed(UserStoryMotivational userStory) + { + switch (userStory.State) + { + case UserStoryState.New: + Console.WriteLine("Before you can finish the code, you should have started implementation"); + break; + case UserStoryState.Active: + Console.WriteLine("I'll notify the testers!"); + userStory.State = UserStoryState.Resolved; + break; + case UserStoryState.Resolved: + Console.WriteLine("The item was already resolved"); + break; + case UserStoryState.Closed: + Console.WriteLine("Item was already closed"); + break; + case UserStoryState.Removed: + Console.WriteLine("Item was removed, you can only move it to backlog again"); + break; + default: + throw new Exception(string.Format("Cannot process user stories that are in {0} state", userStory.State)); + } + } + + public void AcceptanceTestsFail(UserStoryMotivational userStory) + { + switch (userStory.State) + { + case UserStoryState.New: + Console.WriteLine("Implementation did not start yet, probably that's why the tests are failing"); + break; + case UserStoryState.Active: + Console.WriteLine("Implementation is not done yet, probably that's why tests are failing"); + break; + case UserStoryState.Resolved: + Console.WriteLine("We'll notify the devs, that they did a bad job"); + userStory.State = UserStoryState.Active; + break; + case UserStoryState.Closed: + Console.WriteLine("User story is already closed"); + break; + case UserStoryState.Removed: + Console.WriteLine("Item was removed, you can only move it to backlog again"); + break; + default: + throw new Exception(string.Format("Cannot process user stories that are in {0} state", userStory.State)); + } + } + + public void AcceptanceTestsPassed(UserStoryMotivational userStory) + { + switch (userStory.State) + { + case UserStoryState.New: + Console.WriteLine("Development didn't even started, you should check your tests"); + break; + case UserStoryState.Active: + Console.WriteLine("Development is not yet done"); + break; + case UserStoryState.Resolved: + Console.WriteLine("Cool, we'll close the us"); + userStory.State = UserStoryState.Closed; + break; + case UserStoryState.Closed: + Console.WriteLine("User story is already closed"); + break; + case UserStoryState.Removed: + Console.WriteLine("Item was removed, you can only move it to backlog again"); + break; + default: + throw new Exception(string.Format("Cannot process user stories that are in {0} state", userStory.State)); + } + } + } +} diff --git a/src/StatePattern/ScrumExample/ScrumStatePatternExample.cs b/src/StatePattern/ScrumExample/ScrumStatePatternExample.cs new file mode 100644 index 0000000..bd91de0 --- /dev/null +++ b/src/StatePattern/ScrumExample/ScrumStatePatternExample.cs @@ -0,0 +1,295 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace StatePattern.ScrumExample +{ + public class ScrumStatePatternExample + { + public static void Run() + { + UserStory userStory = new UserStory(); + userStory.RemoveFromBacklog(); + userStory.MoveToBacklog(); + userStory.StartImplementation(); + userStory.AcceptanceTestsFail(); + userStory.StartImplementation(); + userStory.AcceptanceTestsPassed(); + + userStory.StartImplementation(); + } + } + + public interface IScrumState + { + void RemoveFromBacklog(); + + void MoveToBacklog(); + + void StartImplementation(); + + void AcceptanceTestsFail(); + + void AcceptanceTestsPassed(); + + void CodeFinishedAnUnitTestsPassed(); + } + + public class UserStory + { + 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; } + + public UserStory() + { + New = new ScrumStateNew(this); + Active = new ScrumStateActive(this); + Resolved = new ScrumStateResolved(this); + Closed = new ScrumStateClosed(this); + Removed = new ScrumStateRemoved(this); + + State = New; + } + public IScrumState State { get; set; } + public int Name { get; internal set; } + + public void AcceptanceTestsFail() + { + State.AcceptanceTestsFail(); + } + + public void AcceptanceTestsPassed() + { + State.AcceptanceTestsPassed(); + } + public void MoveToBacklog() + { + State.MoveToBacklog(); + } + + public void RemoveFromBacklog() + { + State.RemoveFromBacklog(); + } + + public void StartImplementation() + { + State.StartImplementation(); + } + + public void CodeFinishedAnUnitTestsPassed() + { + State.CodeFinishedAnUnitTestsPassed(); + } + } + + internal class ScrumStateNew : IScrumState + { + private UserStory userStory; + + public ScrumStateNew(UserStory userStory) + { + this.userStory = userStory; + } + + public void AcceptanceTestsFail() + { + Console.WriteLine("Implementation did not start yet, probably that's why the tests are failing"); + } + + public void AcceptanceTestsPassed() + { + Console.WriteLine("Development didn't even started, you should check your tests"); + } + + public void CodeFinishedAnUnitTestsPassed() + { + Console.WriteLine("Before you can finish the code, you should have started implementation"); + } + + public void MoveToBacklog() + { + Console.WriteLine("Already in backlog"); + } + + public void RemoveFromBacklog() + { + Console.WriteLine("User story removed"); + } + + public void StartImplementation() + { + Console.WriteLine("Started work on User story: {0}", userStory.Name); + userStory.State = userStory.Active; + } + } + + internal class ScrumStateActive : IScrumState + { + private UserStory userStory; + + public ScrumStateActive(UserStory userStory) + { + this.userStory = userStory; + } + + public void AcceptanceTestsFail() + { + Console.WriteLine("Implementation is not done yet, probably that's why tests are failing"); + } + + public void AcceptanceTestsPassed() + { + Console.WriteLine("Development is not yet done"); + } + + public void CodeFinishedAnUnitTestsPassed() + { + Console.WriteLine("I'll notify the testers!"); + userStory.State = userStory.Resolved; + } + + public void MoveToBacklog() + { + Console.WriteLine("Moved userstory to backlog"); + } + + public void RemoveFromBacklog() + { + Console.WriteLine("You must first move the item to backlog"); + } + + public void StartImplementation() + { + + Console.WriteLine("You can start work only on user stories that are new, current user story state is: {0}", userStory.State); + } + } + + internal class ScrumStateResolved : IScrumState + { + private UserStory userStory; + + public ScrumStateResolved(UserStory userStory) + { + this.userStory = userStory; + } + + public void AcceptanceTestsFail() + { + Console.WriteLine("We'll notify the devs, that they did a bad job"); + userStory.State = userStory.Active; + } + + public void AcceptanceTestsPassed() + { + Console.WriteLine("Cool, we'll close the us"); + userStory.State = userStory.Closed; + } + + public void CodeFinishedAnUnitTestsPassed() + { + Console.WriteLine("The item was already resolved"); + } + + public void MoveToBacklog() + { + Console.WriteLine("Item was already resolved, it can be moved to backlog, only if the acceptance tests failed"); + } + + public void RemoveFromBacklog() + { + Console.WriteLine(@"The item was already resolved, it can be deleted only if the acceptance tests failed and moved to backlog"); + } + + public void StartImplementation() + { + Console.WriteLine("You can start work only on user stories that are new, current user story state is: {0}", userStory.State); + } + } + + internal class ScrumStateClosed : IScrumState + { + private UserStory userStory; + + public ScrumStateClosed(UserStory userStory) + { + this.userStory = userStory; + } + + public void AcceptanceTestsFail() + { + Console.WriteLine("User story is already closed"); + } + + public void AcceptanceTestsPassed() + { + Console.WriteLine("User story is already closed"); + } + + public void CodeFinishedAnUnitTestsPassed() + { + Console.WriteLine("Item was already closed"); + } + + public void MoveToBacklog() + { + Console.WriteLine("Item was already closed, cannot move to new state"); + } + + public void RemoveFromBacklog() + { + Console.WriteLine("Once a User Story is Closed, it cannot be removed"); + } + + public void StartImplementation() + { + Console.WriteLine("You can start work only on user stories that are new, current user story state is: {0}", userStory.State); + } + } + + internal class ScrumStateRemoved : IScrumState + { + private UserStory userStory; + + public ScrumStateRemoved(UserStory userStory) + { + this.userStory = userStory; + } + + public void AcceptanceTestsFail() + { + Console.WriteLine("Item was removed, you can only move it to backlog again"); + } + + public void AcceptanceTestsPassed() + { + Console.WriteLine("Item was removed, you can only move it to backlog again"); + } + + public void CodeFinishedAnUnitTestsPassed() + { + + } + + public void MoveToBacklog() + { + Console.WriteLine("Moved userstory to backlog"); + userStory.State = userStory.New; + } + + public void RemoveFromBacklog() + { + Console.WriteLine("Once a User Story is Closed, it cannot be removed"); + } + + public void StartImplementation() + { + Console.WriteLine("You can start work only on user stories that are new, current user story state is: {0}", userStory.State); + } + } +} diff --git a/src/StatePattern/ScrumExample/UserStory.cs b/src/StatePattern/ScrumExample/UserStory.cs new file mode 100644 index 0000000..3854538 --- /dev/null +++ b/src/StatePattern/ScrumExample/UserStory.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace StatePattern.ScrumExample +{ + public class UserStoryMotivational + { + public String Name { get; set; } + public UserStoryState State { get; set; } + } +} diff --git a/src/StatePattern/ScrumExample/UserStoryState.cs b/src/StatePattern/ScrumExample/UserStoryState.cs new file mode 100644 index 0000000..5128cc3 --- /dev/null +++ b/src/StatePattern/ScrumExample/UserStoryState.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace StatePattern.ScrumExample +{ + public enum UserStoryState + { + New = 0, Active = 1, Resolved = 2, Closed = 3, Removed = 4 + } +} diff --git a/src/StatePattern/StatePatternExamples.cs b/src/StatePattern/StatePatternExamples.cs index 8ffa4a0..70d9a9a 100644 --- a/src/StatePattern/StatePatternExamples.cs +++ b/src/StatePattern/StatePatternExamples.cs @@ -1,4 +1,5 @@ using StatePattern.FanExample; +using StatePattern.ScrumExample; using StatePattern.TVExample; using System; using System.Collections.Generic; @@ -24,6 +25,13 @@ namespace StatePattern GoToNextStep(); FanWithStatePatternExample.Run(); + + GoToNextStep(); + + ScrumMotivationalExample.Run(); + + GoToNextStep(); + ScrumStatePatternExample.Run(); } private static void GoToNextStep()