Readers of this Topics – Application Architect, Developer.
How we can improve our application design. How to use state pattern for a single object with multiple states. Guessing, you have an initial knowledge about GOF design pattern. No? If no, never mind.
- What’s state pattern
- When, where and how to use state pattern
- What’s the main reason to use
- What’s the benefit
Let’s Drill Down the Basic Concept
I have learned the design pattern and I know the implementation. But the question is, why, I need the pattern. If I don’t use any pattern, then nobody ever complain about the code. It means, I can avoid the pattern during my design. Can I do that? Why I will take extra headache?
Scenario-1: Software professional
I’m a software professional and I have to implement micro services application. So, at the beginning, I prepare the architectural design document (say, high level design document). After this phase, I work with developers and implement the design. Finally, I write unit testing. So, I have different roles. The role means an expected behavior associated with a particular position.
Therefore, a software professional has different behaviors depending on the roles or states.
- Architect role: Preparing architectural design document.
- Developer role: Writing codes and implementing the business functionality.
- White-Box Tester Role: Writingtest scenarios, test cases and unit testing.
I had a puppy and on the morning, I likeed to play with it; so, it ran jumped, burked. But suddenly a car crashed it and now it did not move, jump, and burk. So the state has been changed live to dead.
Still have doubt about the scenarios
- Lamp has two states turn on and turn off.
- Water has states, such as – hot, cold, normal, liquid, and solid.
- Person has moods like – angry, happy, sad, tired, and drunk
Therefore, in these scenarios, it is clear that a single object has different states and behaviors.
Design Implementation and Source Code Analysis
In the above image, there is a “DoYourJob” method and I can implement the functionalities using either If-Else statement or switch statement.
Post Mortem Report Analysis
In the above image, I’ve marked numbers such as 1, 2 and 3.
Marked No.1: I’m creating roles in the SoftwareProfessional class. But the problem is, these dependencies are tightly coupled in this class.
As a result, unit testing is not possible for the method of the “DoYourJob”. Why?? Because, according to the first principle, “Test the logic of the class only, nothing else”.
Therefore, if I want unit testing for this class, then it should have to be loosely coupled; otherwise, object mocking is not possible.
Marked No.2 indicates that in future, if I want to extend another role, then I need to create an object in this class.
Marked No.3 indicates that I need to add one more if-else or switch case for the new extended role or state.
Therefore, marked no.2 and 3 are also the violation of the open-closed principle. Because, I want to implement one more roles and its fine; but I shouldn’t touch the “SoftwareProfessional” class. It means, if I implement another role, then I shouldn’t not modify anything into this class.
Why Need Good Design
- Do I need unit testing?
- Do I want to remove if-else or switch-case statement?
- Do I want to remove the code duplication?
- Do I want to minimize implementation effort for future?
- Do I want to minimize the bug?
Considering the above questions, if my answer is – yes, then I need a technique to solve the above problem.
Note: I am considering the above given design and example.
What’s State Pattern
An object changes its behavior according to its state change.
In the class diagram, Context is Software Professional and state is a IRole.
Class diagram for scenerio-2
Removing conditional logic duplication and replacing conditional code with polymorphism.
Damn Good Design
The above example indicates that single object has multiple roles or states and if state changes, then it changes the behavior during runtime. So, considering the State Pattern of the GOF, I can solve this problem.
Good Design Analysis
- Because of the loose coupling, I can mock the object of the IRoleState; as a result, I can test the logic of the method of DoYourJob.
- I have removed the if-else or switch-case statement.
- Anytime, I can implement new IRoleState; but I don’t need to modify the SoftwareProfessional class. So, it satisfies open-closed principle.
- Clean code and easy to understand.
First time, when I learned the if-else statement and for-loop statement and understand that how to apply it to the application, then I realized that I am a developer. You need if-else statement; but you also need to know when and how to use it. If you realize that, then you are on the way to be an excellent developer.