Phase 4레슨 17
Clean Architecture
Dependency Rule, Entity, Use Case, Interface Adapter — 의존성이 안쪽으로만
💡ELI5·
양파와 Clean Architecture
┌─────────────────────────────────┐ │ Frameworks & Drivers (DB, Web) │ 외부 — 변경 가능, 의존함 │ ┌───────────────────────────┐ │ │ │ Interface Adapters │ │ │ │ ┌─────────────────────┐ │ │ │ │ │ Use Cases │ │ │ │ │ │ ┌───────────────┐ │ │ │ │ │ │ │ Entities │ │ │ │ 내부 — 핵심, 독립 │ │ │ └───────────────┘ │ │ │ │ │ └─────────────────────┘ │ │ │ └───────────────────────────┘ │ └─────────────────────────────────┘ Dependency Rule: → 안쪽으로만 의존
💡 비유 — 양파의 속심 = Entity (가장 중요, 변하지 않음). 껍질 = DB, Web Framework (교체 가능). 속심은 껍질이 뭔지 모르지만, 껍질은 속심을 감싼다. 의존성은 껍질 → 속심 방향으로만.
🔬Deep Dive·
4계층 구조
| 계층 | 역할 | 예시 |
|---|---|---|
| Entity | 핵심 비즈니스 규칙, 도메인 객체 | User, Order (순수 객체, 프레임워크 없음) |
| Use Case | 애플리케이션 비즈니스 로직, 사용자 시나리오 | CreateOrderUseCase, LoginUseCase |
| Interface Adapter | 외부와 내부의 변환 (Controller, Presenter, Gateway) | OrderController, OrderDTO, Repository 구현체 |
| Framework/Driver | DB, Web Framework, 외부 서비스 | Express, MySQL, Redis |
🔬Deep Dive·
Dependency Inversion — 핵심 메커니즘
// 내부 (Use Case) — 인터페이스를 정의 (외부를 모름)
interface OrderRepository {
save(order: Order): Promise<void>;
findById(id: string): Promise<Order | null>;
}
class PlaceOrderUseCase {
// 인터페이스에 의존 — 실제 구현체는 외부에서 주입
constructor(private orderRepo: OrderRepository) {}
async execute(items: CartItem[]): Promise<Order> {
const order = Order.create(items);
await this.orderRepo.save(order); // 인터페이스 호출
return order;
}
}
// 외부 (Infrastructure) — 내부 인터페이스를 구현
class MySQLOrderRepository implements OrderRepository {
async save(order: Order) {
await db.query('INSERT INTO orders ...', order);
}
async findById(id: string) {
return db.query('SELECT * FROM orders WHERE id = ?', id);
}
}
// 조립 (Composition Root)
const repo = new MySQLOrderRepository(db);
const useCase = new PlaceOrderUseCase(repo); // 외부 → 내부로 주입Use Case는 MySQL이나 PostgreSQL을 모른다. OrderRepository 인터페이스만 알 뿐. DB를 In-Memory로 바꾸려면 MySQLOrderRepository → InMemoryOrderRepository로 교체하면 된다. Use Case 코드는 변경 없음.
⚖️Trade-off·
Clean Architecture의 장단점
| 장점 | 단점 |
|---|---|
| 도메인이 프레임워크/DB에 독립 | 추상화 계층 많음 (코드량 증가) |
| 테스트 용이 (Mock 주입) | 단순 CRUD에 과도한 구조 |
| 외부 교체 용이 (DB, Framework) | 학습 곡선 가파름 |
| 비즈니스 규칙이 명확히 분리 | 간접 호출로 디버깅 추적 어려움 |
❓ 체크포인트 질문
- 1.Clean Architecture의 Dependency Rule이란?
- 2.Clean Architecture에서 DB를 교체하기 쉬운 이유는?
- 3.Entity와 Use Case의 차이는?
- 4.Clean Architecture의 단점은?
- 5.Clean Architecture에서 인터페이스가 왜 외부가 아닌 내부에 정의되는가?