General Principles
General principles are cross-cutting design heuristics that guide decision-making across all software projects. They transcend specific programming languages, frameworks, and architectural patterns, providing universal guidance for writing code that is maintainable, testable, and resilient to change.
These principles form the foundation upon which more specialized design patterns and architectural approaches are built. They answer fundamental questions: How do we eliminate unnecessary complexity? When should we add features? How do we organize responsibilities? By internalizing these principles, developers build intuition for making good design decisions under uncertainty.
Unlike rigid rules, principles require judgment. They sometimes conflict with each other, and applying them involves trade-offs. The goal is not blind adherence but thoughtful application—understanding the "why" behind each principle so you can make informed decisions about when to apply them and when to break them intentionally.
📄️ DRY
Master DRY principle: eliminate knowledge duplication for maintainable code, improved consistency, and reduced bugs.
📄️ KISS: Keep It Simple, Stupid
Simplicity first: write code that humans understand before optimizing for machines.
📄️ YAGNI: You Aren't Gonna Need It
Avoid speculative generality: implement only features needed today, not imagined future requirements.
📄️ Separation of Concerns
Design systems where different areas address different aspects of functionality, improving modularity and maintainability.
📄️ High Cohesion, Low Coupling
Build systems where components relate strongly to their purpose while remaining loosely connected to other components.
📄️ Composition Over Inheritance
Favor object composition over inheritance to achieve flexibility, reduce fragility, and improve code reuse.
📄️ Law of Demeter
Master the Principle of Least Knowledge to reduce coupling and improve maintainability in complex systems.
📄️ Encapsulate What Varies
Identify volatile aspects of your system and hide them behind stable interfaces to reduce coupling and change impact.
📄️ Fail Fast
Detect and report errors immediately to prevent silent failures, data corruption, and cascading problems.
📄️ Principle of Least Astonishment
Design systems where behavior matches user expectations, minimizing surprise and confusion.
📄️ Immutability Where Possible
Prefer immutable data structures to reduce bugs, improve thread safety, and simplify reasoning about code.