bonggyulim 님의 블로그
SOLID와 클린 아키텍처 본문
SOLID와 클린 아키텍처
1️⃣ 클린 아키텍처란?
클린 아키텍처는 비즈니스 로직을 UI, DB, API 같은 외부 기술로부터 분리하기 위한 아키텍처 설계 방식이다.
핵심은 의존성 방향을 항상 내부(Domain)로 향하게 만드는 것이다.
Presentation → Domain ← Data
| 레이어 | 역할 |
| Presentation | UI 처리 및 상태 관리 |
| Domain | 비즈니스 로직 |
| Data | API, DB 등 데이터 처리 |
Domain 레이어는
- Android
- Retrofit
- Room
같은 외부 기술을 알지 못해야 한다.
2️⃣ 클린 아키텍처 Dependency Rule
클린 아키텍처의 핵심 규칙
바깥 레이어는 안쪽 레이어에 의존할 수 있지만
안쪽 레이어는 바깥 레이어를 알면 안 된다.
예시
ViewModel → UseCase → Repository(interface)
↑
RepositoryImpl
Domain은 Repository 인터페이스만 알고 구현체는 모른다.
3️⃣ SOLID 원칙
SOLID는 객체지향 설계를 위한 5가지 원칙이다.
SRP (Single Responsibility Principle) — 단일 책임 원칙
하나의 클래스는 하나의 책임만 가져야 한다.
UserController → 요청 처리
UserService → 비즈니스 로직
UserRepository → DB 접근
OCP (Open Closed Principle) — 개방 폐쇄 원칙
기존 코드를 수정하지 않고 기능을 확장할 수 있어야 한다.
인터페이스를 정의하고 새로운 기능은 해당 인터페이스를 구현한 클래스를 추가하여 확장한다.
Payment (interface)
↑
CardPayment
KakaoPayment
TossPayment
LSP (Liskov Substitution Principle) — 리스코프 치환 원칙
부모 타입을 사용하는 곳에 자식 타입을 넣어도 정상 동작해야 한다.
payment를 상속받는 다른 클래스로 교체해도 사용 가능해야한다.
PaymentService → Payment(interface)
↑
CardPayment
KakaoPayment
ISP (Interface Segregation Principle) — 인터페이스 분리 원칙
클라이언트가 사용하지 않는 메서드에 의존하지 않도록 인터페이스를 분리한다
Bad
UserRepository
- getUser
- saveUser
- deleteUser
Good
- GetUserRepository
- SaveUserRepository
- DeleteUserRepository
DIP (Dependency Inversion Principle) — 의존 역전 원칙
구체 클래스가 아니라 추상화(인터페이스)에 의존해야 한다
UserService → UserRepository(interface)
↑
UserRepositoryImpl(구체클래스)
4️⃣ SOLID가 클린 아키텍처에 적용되는 방식
SOLID의 클린 아키텍처 적용
| SRP | Presentation / Domain / Data 레이어 분리 |
| OCP | DataSource 확장 가능 (예: 다양한 로그인 방식 구현시 수정없이 기능추가 가능해야함) |
| LSP | Repository 구현체 교체 시 기존 코드가 정상 동작해야 한다 (같은 인터페이스를 구현할 때) |
| ISP | Repository 인터페이스 분리 (클라이언트가 필요없는 메서드 의존하는것 방지) |
| DIP | Domain → Interface 의존 (UseCase는 구현체가 아닌 인터페이스에 의존) |
5️⃣ 왜 클린 아키텍처와 SOLID를 사용하는가?
유지보수가 쉬워진다
UI, 비즈니스 로직, 데이터 처리가 분리되어 있어
코드 수정 시 다른 영역에 영향을 덜 준다.
예
UI 변경 → Presentation만 수정
테스트가 쉬워진다
Domain은 Android나 API에 의존하지 않기 때문에
Unit Test 작성이 쉬워진다.
예
FakeRepository
MockRepository
사용 가능
기술 변경에 유연하다
예
Retrofit → Ktor
Room → Realm
같이 데이터 기술이 바뀌어도 Domain 코드는 수정할 필요가 없다.
확장성이 좋아진다
새로운 기능을 추가할 때 기존 코드를 수정하지 않고
구현체만 추가하면 된다.
예
RemoteDataSource
LocalDataSource
CacheDataSource
'CS & Fundamentals' 카테고리의 다른 글
| I/O 바운드와 CPU 바운드 (0) | 2026.04.06 |
|---|---|
| 디자인패턴이란 (0) | 2026.03.29 |
| 앱에서 API 요청부터 응답까지의 통신 과정 정리 (0) | 2026.03.12 |