Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- 애니메이션
- combine
- MVVM
- map
- 리펙터링
- 리팩토링
- rxswift
- UICollectionView
- ios
- Human interface guide
- uiscrollview
- Refactoring
- SWIFT
- 클린 코드
- RxCocoa
- swift documentation
- Observable
- tableView
- HIG
- 리펙토링
- Clean Code
- UITextView
- 스위프트
- clean architecture
- swiftUI
- Xcode
- Protocol
- uitableview
- collectionview
- ribs
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[Refactoring] 8-5 데이터 조작화 (값을 참조로 바꾸기) 본문
값을 참조로 바꾸기 개념
- 데이터를 공유해야하는 상황에서는 모델을 참조 타입으로 변경
- 데이터를 공유해야할때, 만약 값 타입을 사용하고 있다면 그 데이터를 변경하면 그 데이터의 모든 복제본을 찾아서 빠짐없이 갱신해주는 번거로움이 존재
- 갱신해주다가 만약 하나라도 놓치면 데이터의 일관성이 깨져버리는 현상이 발생
- 값을 참조로 바꾸게 되면 *엔티티(Entity) 하나당 객체도 단 하나만 존재하며, 이런 객체들을 한데 모아 놓고 클라이언트 코드(사용하는 쪽의 코드)들이 접근을 관리해주는 일종의 저장소가 필요
- 엔터티(Entity): 식별 가능한 개체
- ex) 고객이라는 Entity에는 이름, 나이, 주소와 같은 Attribute를 갖음
값을 참조로 바꾸기 리펙토링 해보기
ex) Order 모델 안에 Customer가 있는 상태
- value 타입을 사용하고 있기 때문에 order1의 updateCustomerDate()를 통해 Customer의 date를 변경했을때 order2, order3에도 일일이 다 반영해야하는 상황
struct Customer {
private let id: String
private var date: Date = .init()
init(id: String) {
self.id = id
}
func getID() -> String {
id
}
mutating func updateCustomerDate() {
date = .init()
}
}
struct Order {
private let number: Int
private var customer: Customer
init(number: Int, customerID: String) {
self.number = number
self.customer = Customer(id: customerID)
}
func getCustomer() -> Customer {
customer
}
mutating func updateCustomerDate() {
customer.updateCustomerDate()
}
}
let customerID = "123"
var order1 = Order(number: 0, customerID: customerID)
let order2 = Order(number: 2, customerID: customerID)
let order3 = Order(number: 4, customerID: customerID)
order1.updateCustomerDate()
- 리펙토링
- 1. 같은 부류에 속하는 객체들을 보관할 저장소 생성
- 2. 참조타입으로 변경
- 모델을 참조 타입 (class)로 변경
class RefactorCustomer {
private let id: String
private var date: Date = .init()
init(id: String) {
self.id = id
}
func updateCustomerDate() {
date = .init()
}
}
- 프로토콜 지향 + 저장소를 만들기 위해 프로토콜 정의
protocol Repository {
func registerCustomer(id: String)
func findCustomer(id: String) -> RefactorCustomer?
}
- 프로토콜을 준수하는 저장소를 구현하여 사용
class RepositoryImpl: Repository {
typealias ID = String
var customer = [ID: RefactorCustomer]()
func registerCustomer(id: String) {
customer[id] = RefactorCustomer(id: id)
}
func findCustomer(id: String) -> RefactorCustomer? {
customer[id]
}
}
- 사용하는 쪽(클라이언트 코드)에서는 위 저장소를 통해서 접근하여 사용
값을 참조로 변경할 때의 주의할점
- 같은 부류에 속하는 객체들을 모아놓기 위해서 저장소를 만들었는데, 이 저장소는 전역 저장소로 관리될 수 있기 때문에 웬만하면 DI(Dependency Injection)으로 저장소를 주입해주도록 사용할 것
참고) 반대 리펙토링 - 참조를 값으로 바꾸기
* 참고
- Refactoring (Martin Flowler)
'Refactoring (리펙토링)' 카테고리의 다른 글
[Refactoring] 9-2. 조건부 로직 최소화 (조건문 통합하기) (0) | 2023.05.29 |
---|---|
[Refactoring] 9-1. 조건부 로직 최소화 (조건문 분해하기) (0) | 2023.05.27 |
[iOS - swift] Protocol 지향 프로그래밍 (상속보다 프로토콜을 사용하는게 좋은 이유, 인터페이스, DIP, SRP) (0) | 2023.05.21 |
[Refactoring] 8-4 데이터 조작화 (참조를 값을 바꾸기) (0) | 2023.05.15 |
[Refactoring] 8-3. 데이터 조작화 (파생 변수를 질의 함수로 바꾸기) (0) | 2023.05.14 |
Comments