일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 앱개발
- GCD
- WeatherKit
- RxSwift
- 학과별커뮤니티
- mvc
- 실습
- async
- MVVM
- Optional
- SwiftUI
- 네트워크
- 프로토콜
- struct
- collectionview
- 동시성
- CS
- swift
- 반응형
- Kingfisher
- 스트럭트
- 대표
- 옵셔널
- 이론
- 토이프로젝트
- 기초문법
- 세종대학교
- ios
- uikit
- 구름톤 유니브
- Today
- Total
스윞한 개발자
DAO, DTO, Entity + Repository Pattern 본문
안녕하세요! 이번 포스팅에서는 DAO, DTO, Entity + Repository Pattern에 대해서 정의해 보고!
왜? 써야하는지, 어떻게 써야 하는지에 대해 알아보겠습니다.

우선,
1. DAO (Data Access Object)
- 데이터베이스나 API같은 데이터 소스를 직접 다루는 객체
- 데이터를 읽고 쓰는 구체적인 작업을 담당
- 데이터 저장소에 대한 CRUD 작업을 추상화
정리하자면, DAO는 데이터 저장소와 직접적으로 소통하는 레이어입니다. 비즈니스 로직과 저장소의 로직을 분리하여 유지보수에 용이하게 할 수 있습니다.
예를 들어, 자주 사용하는 로컬 저장소인 UserDefaults를 보여드리겠습니다.
protocol UserDefaultsDAO {
func saveUser(_ user: UserEntity)
func deleteUser(id: Int)
}
class UserDefaultsUserDAO: UserDefaultsDAO {
private let key = "savedUsers"
func saveUser(_ user: UserEntity) {
var users = fetchUsers()
users.append(user)
save(users: users)
}
func deleteUser(id: Int) {
var users = fetchUsers()
users.removeAll { $0.id == id }
save(users: users)
}
}
위와 같이, 구현할 수 있습니다.
이유는?
저장소가 바뀌어도 비즈니스 로직은 그대로 유지가 가능합니다. 즉, 저장이나 삭제를 할 때마다 매번 UserDefaults를 직접 호출해줘야 합니다. 또한 데이터의 읽기/쓰기에 대한 책임은 DAO만 가지게 됩니다. 서비스에서 비즈니스 로직과 저장소 접근 관련 로직이 뒤섞이면 유지보수가 어려워지게 됩니다.
2. DTO (Data Transfer Object)
- 네트워크 통신 시 주고받는 데이터의 구조
- API 응답/요청의 스펙에 맞춘 데이터 모델
- Codable 프로토콜로 정의
DTO를 사용하게 되면, API와 인터페이스를 깔끔하게 유지가 가능합니다. 서버의 응답형태와 앱의 내부 모델과 다를때 변환이 편리합니다.
struct UserDTO: Codable {
let id: Int
let name: String
let email: String
}
위의 DTO를 통해 앱 내부에서 사용되는 Entity로 변환해 쉽게 사용할 수 있습니다.
3. Entity
- 앱 내부의 도메인 모델
- 비즈니스 로직 포함 가능(데이터 가공, 값 변환, 검증 로직 등)
앱의 비즈니스 로직 중심 데이터 구조입니다. API 응답 결과과 100% 같지 않아도 되며, DTO에서 매핑하여 Entity로 변환해 사용할 수 있습니다.
struct UserEntity {
let id: Int
let nickname: String
let email: String
var isUser: Bool {
return email.contains("k")
}
}
# 이유는?
API응답 데이터 구조가 바뀌어도, DTO만 수정하면 되고, 내부의 비즈니스 로직에는 영향이 없기 때문에 보통은 따로 두어 구현하는 편입니다. 또한 앱 내부에서 필요한 데이터만 Entity에 담아 제공하기 때문에 불필요한 데이터를 제외할 수 있습니다.
extension UserDTO {
func toEntity() -> UserEntity {
return UserEntity(id: id, nickname: name, email: email)
}
}
이와 같이, DTO에서 toEntity를 통해 바로 앱내에서 사용할 수 있도로 구현이 가능합니다.
4. Repository Pattern
- DAO와 도메인 모델 사이에서 데이터 소스 추상화 역할
- DB에서 데이터를 가져오든, API에서 데이터를 가져오든 Repository가 감춤
- 세부적인 데이터 소스를 모르는 상태에서도 Repository 인터페이스만 보면 데이터의 핸들링이 가능
# DTO는 데이터 전송을 단순화하고, Repository 패턴은 데이터의 접근을 추상화하여 코드의 유지보수성을 높임.
# 이유는??
Repository 패턴은 데이터의 접근을 추상화하여, 데이터베이스나 네트워크와의 상호작용을 관리하는 패턴입니다. 이 패턴을 사용한다면, 데이터로부터 접근하는 로직을 분리하여 유지보수성을 높일 수 있습니다. 왜냐하면, Repository 패턴은 데이터 접근 로직을 한 곳에 모아 관리할 수 있기 때문입니다.
(데이터를 어떻게 가져올지 숨기고, 필요한 데이터만 꺼내 쓸 수 있게 중간에서 정리해 주는 "데이터 전담 매니저"의 역할!!)
protocol RecipeRepository {
func fetchRecipes() -> [RecipeDTO]
}
class RecipeRepositoryImpl: RecipeRepository {
func fetchRecipes() -> [RecipeDTO] {
// 데이터베이스나 네트워크에서 데이터를 가져오는 로직
}
}
앱에서 데이터를 가져올 때, 데이터는 여러 곳에서 가져올 수 있습니다.
1. 서버(API)
2. 로컬 DB
...등등
그래서 데이터를 가져오는 방법을 숨기고, 필요한 데이터만 깔끔하게 꺼내주기 위해 위의 패턴을 사용합니다.
결론은!
각각의 패턴을 잘 활용하면 개발에서 훨씬 효율적인 코드를 작성할 수 있습니다. 데이터 전송과 접근 로직을 효율적으로 관리할 수 있습니다.
DTO를 활용하면 데이터 전송을 단순화하고, Repository 패턴은 데이터의 접근을 추상화하여 코드의 유지보수성을 높이기 때문입니다.
결국에는 "변경이 생길 때, 영향 범위를 최소화"하는 것!입니다.
나중에 뭔가 변경이 생기더라도 고칠 곳이 최소한이 되도록 만드는 것입니다. -> 변경에 유연한 구조!
만약 DTO가 없이 사용했다면, 필드 이름이 바뀌게 되면 화면의 코드를 전부 수정해야 합니다. 또한 Repository 없이 사용했다면, UserDefaults -> Realm/CoreData로 바꾼다면, 여러 군데에 퍼져있던 UserDefaults 코드를 모두 변경해야 하지만, Repository 안에서 저장소 변경 및 처리가 가능합니다.
예를 들면,
UserDefaults 직접 접근 | 수정 어려움 (여러 군데 수정) | 낮음 | 테스트 어려움 (UserDefaults 직접 필요) |
Repository 사용 | 수정 쉬움 (Repository만 수정) | 높음 | 테스트 쉬움 (MockRepository 가능) |
이번 포스팅에서는 DAO, DTO, Entity + Repository Pattern에 대해 알아보았습니다. 이제 적절하게 프로젝트 내에서 녹여야겠습니다..ㅎㅎ 긴 글 읽어주셔서 감사합니다!
잘못된 내용에 대한 피드백은 언제나 환영입니다. 감사합니다!!

아래의 글들을 참고해 작성되었습니다.
https://f-lab.kr/insight/ios-development-dto-repository-pattern-20240717
DTO와 레파지토리 패턴을 활용한 iOS 개발
이 글에서는 iOS 개발에서 DTO와 레파지토리 패턴의 중요성과 이를 활용한 프로젝트 관리 및 테스트 방법에 대해 설명합니다. 실제 코드 예제를 통해 이해를 돕고, 관련된 이론과 기술을 소개합니
f-lab.kr
'Swift 이론' 카테고리의 다른 글
DB Transaction / ACID (0) | 2025.03.17 |
---|---|
Hot/Cold Observable, Multi/UniCast (1) | 2025.03.04 |
DiffableDatasource의 이해 (0) | 2025.02.16 |
iOS - ARC(Swift 메모리 관리 기법) (2) | 2025.02.09 |
Actor 톺아보기 👀 (1) | 2025.02.04 |