Understanding Object-Oriented Principles
1. Understanding Encapsulation
| Aspect | Mechanism | Java Modifier |
|---|---|---|
| Data hiding | Restrict direct field access | private |
| Controlled access | Getter/setter methods | public |
| Package-private | Same package only | (default) |
| Subclass access | Inheritance hierarchy | protected |
| Invariant guard | Validation in setters | throw on invalid |
Example: Encapsulated balance
public final class Account {
private long balanceCents;
public long getBalanceCents() { return balanceCents; }
public void deposit(long cents) {
if (cents <= 0) throw new IllegalArgumentException("positive only");
this.balanceCents += cents;
}
}
2. Understanding Abstraction
| Type | Construct | Use Case |
|---|---|---|
| Procedural | Method extraction | Hide algorithm steps |
| Data | ADTs, classes | Hide representation |
| Behavioral | Interfaces | Hide implementation |
| Polymorphic | Abstract classes | Partial implementation |
Example: Payment abstraction
public interface PaymentGateway {
PaymentResult charge(Money amount, Card card);
}
// Callers depend only on the contract, not Stripe/PayPal details.
3. Understanding Inheritance
| Type | Java Syntax | Notes |
|---|---|---|
| Single class | class B extends A | One superclass only |
| Multiple interface | class B implements X, Y | No diamond problem |
| Sealed | sealed class S permits A, B Java 17+ | Closed hierarchy |
| Final | final class F | Cannot subclass |
Warning: Prefer composition; deep inheritance creates fragile base class problems.
4. Understanding Polymorphism
| Form | Mechanism | Resolution |
|---|---|---|
| Subtype (dynamic) | Method override | Runtime dispatch |
| Parametric | Generics <T> | Compile-time |
| Ad-hoc | Method overloading | Compile-time signature |
| Coercion | Implicit conversions | Type promotion |
Example: Subtype polymorphism
List<Shape> shapes = List.of(new Circle(2), new Square(3));
double total = shapes.stream().mapToDouble(Shape::area).sum();
5. Understanding Composition over Inheritance
| Concern | Inheritance | Composition |
|---|---|---|
| Coupling | Tight (parent internals) | Loose (interface only) |
| Flexibility | Fixed at compile time | Swap at runtime |
| Reuse | "Is-a" | "Has-a" |
| Testability | Harder (mock parent) | Inject mock collaborator |
Example: Compose, don't extend
// BAD: class CachingUserService extends UserService { ... }
// GOOD:
public class CachingUserService implements UserService {
private final UserService delegate;
private final Cache<Long, User> cache;
public User find(long id) {
return cache.get(id, delegate::find);
}
}
6. Understanding Coupling and Cohesion
| Metric | Goal | Indicator |
|---|---|---|
| Coupling | Low | Few external dependencies, abstract types |
| Cohesion | High | Methods operate on same fields/concept |
| Afferent (Ca) | Tracked | How many depend on this |
| Efferent (Ce) | Low | How many this depends on |
| Instability I | Stable for core | Ce / (Ca + Ce) |
7. Understanding Information Hiding
| Hide | Technique |
|---|---|
| Implementation | Program against interfaces |
| Internal state | private + immutability |
| Construction | Static factories, builders |
| Module internals | Java module exports selectively |
8. Understanding Separation of Concerns
| Layer | Responsibility |
|---|---|
| Controller | HTTP I/O, validation |
| Service | Business workflow, transactions |
| Domain | Business rules, invariants |
| Repository | Persistence |
| Infrastructure | External systems (HTTP, MQ) |
9. Understanding Law of Demeter
| Rule | Allowed Calls |
|---|---|
| "Talk to friends" | Self, parameters, fields, created objects |
| Forbidden | Chained a.getB().getC().doX() |
Example: Tell, don't ask
// BAD: order.getCustomer().getAddress().getStreet()
// GOOD:
order.shipTo(label); // order knows how to expose what's needed
10. Understanding DRY Principle
| Aspect | Fix |
|---|---|
| Duplicate logic | Extract method/class |
| Duplicate constants | Centralize in constants class |
| Duplicate knowledge | Single source of truth |
Warning: Avoid premature DRY — coincidental duplication should not be merged.
11. Understanding YAGNI Principle
| Symptom | Action |
|---|---|
| "Maybe we'll need..." | Don't build it |
| Speculative interface | Inline until 2nd caller |
| Unused config knob | Remove |
12. Understanding KISS Principle
| Sign of complexity | Simplification |
|---|---|
| Deep nesting | Guard clauses, early return |
| Long methods | Extract method |
| Clever one-liner | Readable multi-line |
| Generic everywhere | Concrete until needed |