Skip to main content

Single State Handling

Description​

What does it look like?​

  • Object behavior varies by internal state, but state and behavior are tightly coupled
  • State-specific behavior is managed using if or switch statements
  • As states increase, the logic bloats and becomes harder to read

Why is it a problem?​

  • Each new state requires modifying existing code (violates the Open/Closed Principle)
  • Responsibilities are concentrated in a single class, leading to low readability and difficult testing
  • Future expansions and state transition logic become complex and error-prone

Bad Example of the Anti-pattern​

class Document {
private state: string = "draft"; // ηŠΆζ…‹: 'draft', 'review', 'published'

publish() {
if (this.state === "draft") {
console.log("レビγƒ₯ー依頼を送俑");
this.state = "review";
} else if (this.state === "review") {
console.log("ε…¬ι–‹γ—γΎγ—γŸ");
this.state = "published";
} else if (this.state === "published") {
console.log("γ™γ§γ«ε…¬ι–‹ζΈˆγΏγ§γ™");
}
}
}

Issues:​

  • State is managed as a plain string, and behavior is centralized in a single method
  • Whenever a new state is added, publish() must be modified
  • Mixing state and logic in one place makes the design fragile and hard to extend

Refactoring by Pattern​

Design patterns that can address this​

PatternOverviewMain Refactoring Approach
StateSeparate objects by state and delegate behaviorManage state explicitly using classes
StrategyReplace behavior externallyLet external context control state switching
CommandEncapsulate state-specific actions as command objectsRepresent behavior as objects for flexibility