반응형
SwiftUI에서 많이 하는 실수 - 도메인 모델과 UI 전용 모델을 구분하지 않는 실수
도메인 모델(Domain Model)은 비즈니스 규칙 중심,
UI 모델(View Model / UI DTO)은 화면 표현 중심이어야 합니다.
이 둘을 동일 구조체/클래스로 사용하면,
도메인 로직이 UI 요구사항에 끌려 다니거나, 반대로 UI가 도메인 제약에 막혀 불편해집니다.
1. 문제 원인
- “모델 하나 만들었으니 그냥 어디서나 쓰면 되겠지”라고 생각
- 포맷팅된 문자열(예: 3,000원, 2024.01.01)을 그대로 도메인에 넣음
- 서버 DTO → 도메인 → UI 사이 변환 계층을 만드는 것을 귀찮아함
2. 나타나는 증상
- 통화/날짜/단위 표기 방식 변경 시, 도메인 전체를 수정해야 함
- UI 요구로 인해 도메인 모델에 isSelected, cellHeight 같은 필드가 추가됨
- 테스트나 재사용 관점에서 도메인 모델이 UI에 너무 의존적이 됨
3. 잘못된 코드 예시
struct Card {
// ❌ UI 포맷 문자열을 도메인에 직접 저장
let id: UUID
let title: String
let balanceText: String // "3,000원"
let createdAtText: String // "2024.01.01"
var isSelected: Bool // 셀 선택 여부
}
- 포맷이 바뀌면 도메인 정의 자체가 바뀌어야 합니다.
4. 올바른 코드 예시
4-1. 도메인 모델
struct Card {
let id: UUID
let title: String
let balance: Int // 원 단위 금액
let createdAt: Date
}
4-2. UI 전용 ViewModel / DTO
struct CardRowViewModel: Identifiable {
let id: UUID
let title: String
let balanceText: String
let createdAtText: String
var isSelected: Bool
init(card: Card, isSelected: Bool, formatter: NumberFormatter, dateFormatter: DateFormatter) {
self.id = card.id
self.title = card.title
self.balanceText = formatter.string(from: card.balance as NSNumber) ?? "\(card.balance)원"
self.createdAtText = dateFormatter.string(from: card.createdAt)
self.isSelected = isSelected
}
}
View에서는 이 UI 전용 모델을 사용:
struct CardRow: View {
let viewModel: CardRowViewModel
var body: some View {
HStack {
Text(viewModel.title)
Spacer()
Text(viewModel.balanceText)
}
}
}
5. 정리 및 팁
- 도메인 모델에는 순수한 데이터와 비즈니스 규칙만 넣습니다.
- 화면 표시용 문자열, 색상, 이미지 이름 등은 UI 전용 구조체/뷰모델에서 책임지게 만드는 것이 좋습니다.
- 이 분리를 해두면
- 여러 UI(SwiftUI, UIKit, 위젯, watchOS)에서 같은 도메인을 재사용하기 쉽고
- 다국어/통화/날짜 포맷 변경에도 도메인이 흔들리지 않습니다.
반응형
'Dev Study > SwiftUI' 카테고리의 다른 글
| SwiftUI에서 많이 하는 실수 - 하나의 상태를 여러 곳에서 동시에 수정해 충돌이 나는 실수 (1) | 2025.12.05 |
|---|---|
| SwiftUI에서 많이 하는 실수 - AppStorage / SceneStorage를 남용해 예기치 않은 상태 유지가 발생하는 실수 (0) | 2025.12.05 |
| SwiftUI에서 많이 하는 실수 - View 중첩이 지나치게 깊어져 가독성과 유지보수가 나빠지는 실수 (0) | 2025.12.05 |
| SwiftUI에서 많이 하는 실수 - Modifier 순서를 이해하지 못해 스타일이 적용되지 않는 실수 (0) | 2025.12.05 |
| SwiftUI에서 많이 하는 실수 - Preview에서 실제와 다른 상태를 구성해 놓고 디버깅이 꼬이는 실수 (0) | 2025.12.05 |
| SwiftUI에서 많이 하는 실수 - onChange(of:)를 잘못 사용해 과도한 리렌더링이 일어나는 실수 (0) | 2025.12.05 |
| SwiftUI에서 많이 하는 실수 - animation()을 남발해 의도치 않은 애니메이션이 발생하는 실수 (0) | 2025.12.05 |
| SwiftUI에서 많이 하는 실수 - List 셀 내부에서 상태 변경/로직을 수행해 무한 렌더링이 발생하는 실수 (0) | 2025.12.05 |

