# OOP Programming Guide

## Core Philosophy

```
Flexibility is not always the top priority. Gaining flexibility can cost readability.
```

Use flexibility only where needed. Excessive generalization and class separation harm readability.

---

## Dependency & Coupling

### Principles
- Dependency itself is not the problem. **The degree of coupling** is the problem
- Tight Coupling: Modifying the dependency requires many modifications to the dependent
- Loose Coupling: Modifying the dependency requires little to no modification to the dependent

### Coupling Mitigation Methods
| Problem | Solution |
|---------|----------|
| Constructor change coupling | DI (Dependency Injection) |
| Injected class coupling | Polymorphism (depend on parent type) |

### Decoupling Trade-off
- Advantages: Better flexibility, reusability
- Disadvantages: Reduced intuitiveness, potential efficiency loss

---

## Function

### Core Principle
```
The function signature alone should convey the precondition, behavior, and result.
```

| Element | Representation |
|---------|----------------|
| Precondition | parameter |
| Behavior | method name |
| Result | return value |

### Separation of Responsibility
- **Caller**: Uses the signature only, does not depend on internal implementation
- **Function**: Behaves according to the signature contract; if inconsistent, modify internals or change signature

### Naming Convention
- Values with units: suffix with `In{unit}` (e.g., `amountInEther`, `distanceInKm`)
- State modification verbs:
  - `set`: Overwrite existing value
  - `add`: Add single item
  - `update`: Add multiple items
- Prefer role-based naming over behavior-based naming

---

## Class

### Core Principles

**1. Express intent concretely**
- Clearly express what is open and closed for extension
- Don't make everything easily changeable
- Make **constraints explicit** to prevent unintended usage

**2. The object itself is the agent of state change**
- External code instructs behavior (method call) → Object changes its own state
- Design to prevent external direct state modification

**3. Limit interaction targets**
- Open interaction targets increase potential bugs
- Limit allowable input targets via type/interface

**4. Apply final keyword by default**
- Apply final to both classes and methods by default
- Exceptions: Classes that need inheritance, externally distributed libraries

**5. Keep polymorphism scope narrow**
- Extract only behavior that needs polymorphism into separate methods

### Constructor
```
After constructor call, the object must be immediately usable without additional initialization.
```

### Member Variables & Methods
- `getter`: Create freely
- `setter`: Define only when needed, restrict input with type/enum
- Derivable values: Declare only the source as member (e.g., store seconds only, calculate hours/minutes)
- Avoid Temporal Coupling (method call order dependency)

### Inheritance
- Implementation direction: Create multiple objects first, then extract common parts to parent
- **Limit inheritance depth to 2 levels or less**
- When multiple inheritance is needed: Use abstract methods or Interfaces

### Inheritance vs Composition
| Criterion | Choice |
|-----------|--------|
| Polymorphism needed | Inheritance |
| has-a relationship | Composition |
| is-a relationship | Inheritance |
| Deep inheritance | Composition |

### Abstract Class & Interface
- **Abstract Class**: When there's no practical reason to instantiate the parent class
- **When to use Interface**:
  - Multiple inheritance + polymorphism needed
  - Preparing for change (externally provided library, external clients)
- Interface naming: Recommend `~able` suffix (Readable, Attachable)

---

## Exception

### Terminology
| Term | Description |
|------|-------------|
| Happy Path | Normal business logic |
| Exceptional Case | External exceptions (library errors, File IO, etc.) |
| Bug | Unrecognized problems |

### Handling Principles

**1. Catch in one place**
```
Handle catch blocks in one core entry point like main().
```
Multiple throw/catch across codebase makes management difficult

**2. External boundary vs Internal**
- **External boundary** (uncontrollable): Exception handling required, validate input/output
- **Internal** (controllable): Assume no exceptions, avoid excessive validation

**3. Preserve call stack when re-throwing**

**4. Bug response: Logging**
- Catch exceptions in main() and log them

---

## Quick Reference

### Do
| Area | Principle |
|------|-----------|
| Common | Use flexibility only where needed |
| Function | Make role understandable from signature alone |
| Function | Specify units with suffix (InMl, InKm) |
| Function | Distinguish set/add/update |
| Class | Express intent concretely, make constraints clear |
| Class | Object changes its own state |
| Class | Apply final by default |
| Class | Getters freely, setters only when needed |
| Class | Limit inheritance depth to 2 levels |
| Exception | Catch at one entry point |
| Exception | Validate at external boundaries |

### Don't
| Area | Principle |
|------|-----------|
| Common | Unconditional decoupling |
| Function | Design requiring internal knowledge to use |
| Class | Temporal coupling |
| Class | Separate members for derivable values |
| Class | Require additional initialization after constructor |
| Class | Deep inheritance (3+ levels) |
| Exception | Excessive exception handling in internal logic |
| Exception | Multiple scattered try-catch blocks |
