Master Practical Java Design Patterns!
Subscribe to Ram N Java for clean code walkthroughs, Gang of Four (GoF) design patterns, and real-world Java implementations!
🔔 Subscribe to Ram N JavaThe Problem: Nested Conditionals in State Transitions
Consider an everyday electronic device like an LED TV. An LED TV can exist in multiple distinct states—such as Turned On or Turned Off. When a user presses the power button or executes an action, the behavior completely depends on the current operational state:
- If the TV is currently Off, pressing the power button powers up the display.
- If the TV is currently On, pressing the power button switches the display off and puts it into standby mode.
In conventional procedural code, this behavior is implemented using large if-else or switch-case blocks. As you introduce additional states (such as Standby, Mute, or Input Selection), the conditional logic becomes fragile, cluttered, and difficult to maintain.
The Solution: Applying the State Design Pattern
The State Design Pattern solves this problem by encapsulating individual state behaviors into dedicated classes and delegating execution to the current state object:
-
State Interface: Defines a common interface (e.g.,
State) declaring operations that every concrete TV state must implement (e.g.,doAction()). -
Concrete States: Classes like
TVStartStateandTVStopStateimplement state-specific execution logic and trigger state transitions. - Context Class (TVContext): Maintains a reference to the current state instance, delegating client requests to it rather than handling conditional branches internally.
Architectural Advantages of the State Pattern
Encapsulating state logic into discrete objects offers immediate software engineering benefits:
- Elimination of Bulky Conditionals: Replaces messy conditional branches with clean polymorphic method invocation.
- Single Responsibility Principle: Organizes state-specific code into isolated classes, making each state easy to read and test.
- Open/Closed Principle: Adding new TV states (e.g.,
TVSleepState) requires introducing a new class without modifying existing state handlers.
Related Tutorials from Ram N Java
Click here to watch in Youtube : https://www.youtube.com/watch?v=RZ_RI602pMY
Click the below Image to Enlarge
| State Design pattern - Implementation [LED TV] |
| State Design pattern - Implementation [LED TV] |
| State Design pattern - Implementation [LED TV] - Class Diagram |
StateOfLedTv.java
public interface StateOfLedTv
{
public void doTurnOnOrOff();
}
LEDTVOffState.java
public class LEDTVOffState implements StateOfLedTv
{
@Override
public void doTurnOnOrOff()
{
System.out.println("TV is turned OFf");
}
}
LEDTVOnState.java
public class LEDTVOnState implements StateOfLedTv
{
@Override
public void doTurnOnOrOff()
{
System.out.println("TV is turned ON");
}
}
LEDTVContext.java
public class LEDTVContext implements StateOfLedTv
{
private StateOfLedTv stateOfLedTv;
public StateOfLedTv getStateOfLedTv()
{
return stateOfLedTv;
}
public void setStateOfLedTv(StateOfLedTv stateOfLedTv)
{
this.stateOfLedTv = stateOfLedTv;
}
@Override
public void doTurnOnOrOff()
{
System.out.println("Current state : " + stateOfLedTv.getClass().getName());
stateOfLedTv.doTurnOnOrOff();
}
}
TVRemote.java
public class TVRemote
{
public static void main( String[] args )
{
LEDTVContext context = new LEDTVContext();
StateOfLedTv ledTvOnState = new LEDTVOnState();
StateOfLedTv ledTvOffState = new LEDTVOffState();
context.setStateOfLedTv(ledTvOnState);
context.doTurnOnOrOff();
context.setStateOfLedTv(ledTvOffState);
context.doTurnOnOrOff();
}
}
Output
Current state : LEDTVOnState
TV is turned ON
Current state : LEDTVOffState
TV is turned OFf
No comments:
Post a Comment