Java > Design Patterns in Java > Behavioral Patterns > State Pattern
State Pattern Example: Document State Management
This example demonstrates the State pattern by modeling the different states of a document (Draft, Moderation, Published). The document's behavior changes based on its current state.
Introduction to the State Pattern
The State pattern is a behavioral design pattern that allows an object to alter its behavior when its internal state changes. This pattern encapsulates state-specific behavior into separate classes, known as state classes. The context object delegates behavior to its current state, allowing it to behave differently depending on the state.
DocumentState Interface
This interface defines the contract for all document states. It specifies the methods that can be called on a document in any state (in this example, `publish` and `moderate`).
interface DocumentState {
void publish(Document document);
void moderate(Document document);
}
DraftState Class
This class represents the 'Draft' state of the document. When `publish` is called, it transitions the document to the 'Moderation' state. `moderate` operation will output that the document is already in draft state.
class DraftState implements DocumentState {
@Override
public void publish(Document document) {
System.out.println("Sending document to moderation...");
document.setState(new ModerationState());
}
@Override
public void moderate(Document document) {
System.out.println("Document is already in draft state, nothing to moderate.");
}
}
ModerationState Class
This class represents the 'Moderation' state. Calling `moderate` transitions the document to the 'Published' state. If already published it output to the console.
class ModerationState implements DocumentState {
@Override
public void publish(Document document) {
System.out.println("Document is already in moderation.");
}
@Override
public void moderate(Document document) {
System.out.println("Moderating the document...");
document.setState(new PublishedState());
}
}
PublishedState Class
This class represents the 'Published' state. In this state, publishing or moderating is not allowed.
class PublishedState implements DocumentState {
@Override
public void publish(Document document) {
System.out.println("Document is already published.");
}
@Override
public void moderate(Document document) {
System.out.println("Cannot moderate a published document.");
}
}
Document Class (Context)
The `Document` class is the context. It holds the current `DocumentState` and delegates calls to the `publish` and `moderate` methods to the current state. The initial state is set to 'Draft'.
class Document {
private DocumentState state;
public Document() {
this.state = new DraftState();
}
public void setState(DocumentState state) {
this.state = state;
}
public void publish() {
state.publish(this);
}
public void moderate() {
state.moderate(this);
}
}
Example Usage
This demonstrates how to use the State pattern. The `Document` object's behavior changes based on its current state.
public class StatePatternExample {
public static void main(String[] args) {
Document document = new Document();
document.publish(); // Sends document to moderation
document.moderate(); // Moderating the document...
document.publish(); // Document is already published.
}
}
Concepts Behind the Snippet
The core concept is to encapsulate state-specific behavior within state classes. This promotes the Single Responsibility Principle and Open/Closed Principle. The context object maintains a reference to the current state and delegates requests to it.
Real-Life Use Case
Consider a TCP connection. Its states can be: `CLOSED`, `LISTEN`, `SYN_SENT`, `SYN_RECEIVED`, `ESTABLISHED`, etc. The behavior of the connection changes dramatically depending on its current state. For example, what happens when data is received depends entirely on the connection's state.
Best Practices
Interview Tip
Be prepared to explain the benefits of the State pattern compared to using conditional statements (if/else or switch) to manage state. Highlight the advantages of encapsulation, maintainability, and extensibility.
When to use them
Use the State pattern when:
Memory footprint
The memory footprint depends on the number of state objects and the data they hold. Generally, it's not a significant concern, but if you have a very large number of states or state objects, consider optimizing memory usage.
Alternatives
Alternatives to the State pattern include:
Pros
Cons
FAQ
-
What is the difference between the State and Strategy patterns?
Both patterns encapsulate behavior in separate classes. However, the intent is different. The Strategy pattern is used to choose between different algorithms, while the State pattern is used to manage the state of an object over time. -
When should I use the State pattern instead of simple if/else statements?
Use the State pattern when your code involves a complex set of state-dependent behaviors and the state of the object changes frequently. If/else statements can become difficult to manage and maintain in such scenarios.