Application Design
Readers of this Topics - Application Architect, Developer
Coverage Topic
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
My Problem
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 complains about the code. It means that I can avoid the pattern during my design. Can I do that? Why should I take extra headache?
Investigation
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: Writing test scenarios, test cases and unit testing
Scenario 2
I had a puppy and in the morning, I liked to play with it; so, it ran, jumped, barked. But suddenly, a car hit it and now it does not move, run, jump, and bark. So the state has been changed from 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.
Implementation Magic
Class Diagram
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 role and it's fine; but I shouldn’t touch the “SoftwareProfessional
” class. It means, if I implement another role, then I shouldn't 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 SoftwareProfessional
and state
is an IRole
.
Class Diagram for Scenario 2
Advantages
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.
Class Diagram
Design Implementation
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 the open-closed principle. - Clean code and easy to understand.
Demo Time!!
The first time when I learned the if
-else
statement and for
-loop statement and understand 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 being an excellent developer.