QUICK REFERENCE

Design Principles Cheat Sheet

Essential software design principles beyond SOLID for cleaner, maintainable code.

Efficiency

DRY

Don't Repeat Yourself. Every piece of knowledge must have a single, unambiguous representation.

// BAD: Logic repeated
void saveUser(User u) {
db.connect(); db.save(u);
}
void saveOrder(Order o) {
db.connect(); db.save(o);
}
// GOOD: Abstracted logic
void save(Object o) {
db.connect(); db.save(o);
}
Simplicity

KISS

Keep It Simple, Stupid. Simplicity should be a key goal in design, and unnecessary complexity should be avoided.

// BAD: Over-engineered
public String getDay(int day) {
return new DateFormatSymbols().getWeekdays()[day];
}
// GOOD: Simple & Readable
public String getDay(int day) {
String[] days = {"Sun", "Mon", "Tue", ...};
return days[day];
}
Efficiency

YAGNI

You Aren't Gonna Need It. Do not implement functionality until it is necessary.

// BAD: Speculative Generality
class User {
String name;
String unusedFutureField; // Don't do this
void futureMethod() { ... }
}
// GOOD: Only what's needed now
class User {
String name;
}
Coupling

Law of Demeter

Principle of Least Knowledge. Only talk to your immediate friends.

// BAD: Chaining calls (Train wreck)
person.getAddress().getCountry().getCode();
// GOOD: Delegate method
person.getCountryCode();
Structure

Composition > Inheritance

Favor 'HAS-A' relationships over 'IS-A'. It allows dynamic behavior change and prevents brittle hierarchies.

// BAD: Fragile Inheritance
class Bird { void fly() {} }
class Penguin extends Bird { /* Can't fly! */ }
// GOOD: Composition
class Penguin {
private Movement movement = new Swim(); // HAS-A
}
Control

Hollywood Principle

"Don't call us, we'll call you." High-level components determine when and how low-level components are used (Inversion of Control).

// Framework calls your code (IoC)
class MyHandler implements Handler {
@Override
public void handle() {
System.out.println("Called by Framework");
}
}
Maintainability

Encapsulate Change

Identify the aspects of your application that vary and separate them from what stays the same.

// Encapsulate tax calculation which varies
interface TaxCalculator {
double calculate(double amount);
}
// Logic that stays same uses the interface
class Order {
void process(TaxCalculator tax) { ... }
}
Stability

Fail Fast

Report errors immediately rather than continuing with invalid state.

public void process(User user) {
if (user == null) {
throw new IllegalArgumentException("User cannot be null");
}
// Continue logic...
}
Flexibility

Program to Interface

Program to an interface, not an implementation. Depends on abstractions.

// BAD
ArrayList<String> list = new ArrayList<>();
// GOOD
List<String> list = new ArrayList<>();