SOLID, Design Patterns, and State Machines
SOLID principles are heuristics for reducing change coupling. Single Responsibility seeks one cohesive reason to change; Open/Closed encourages extending stable behavior without repeated edits; Liskov Substitution preserves subtype contracts; Interface Segregation keeps interfaces focused; Dependency Inversion separates policy from volatile implementation details. Applying an interface to every class can add needless indirection, so use abstractions where change, testing, or multiple implementations justify them.
Common patterns include Strategy for interchangeable algorithms, Factory for varying construction, Adapter for incompatible interfaces, Observer for event notification, Decorator for layered behavior, and Command for representing an operation as data. Patterns are useful when they clarify variation; they are not goals in themselves.
State machines are particularly useful for payments, orders, uploads, and durable workflows. Define valid states, transitions, triggers, side effects, and terminal states. Persist important transitions and make side effects idempotent because an in-memory state machine alone cannot recover after a process restart.
- Use design patterns to reduce coupling, not to add ceremony.
- Model lifecycle rules as explicit state transitions.
- Persist and observe business-critical workflow state.