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
- map
- Xcode
- Observable
- combine
- ios
- Human interface guide
- rxswift
- 리팩토링
- RxCocoa
- 스위프트
- uitableview
- tableView
- swift documentation
- MVVM
- uiscrollview
- 리펙터링
- 애니메이션
- 클린 코드
- ribs
- SWIFT
- clean architecture
- collectionview
- Protocol
- Refactoring
- HIG
- UITextView
- UICollectionView
- Clean Code
- 리펙토링
- swiftUI
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[Refactoring] 8-4 데이터 조작화 (참조를 값을 바꾸기) 본문
참조를 값으로 바꾸기
- 참조 타입 vs 값 타입
- 참조로 데이터를 다룰 땐 객체는 그대로 둔 채 그 객체의 속성만 변경
- 값으로 데이터를 다룰 땐 새로운 속성을 담은 새로운 객체로 초기화하며 영향력은 복사된 곳에서만 고려됨
- 참조 타입의 데이터 구조를 사용하면 이 데이터가 다른곳에 건네줄때 이 값이 마음대로 바뀔수 있음
- 값 타입은 불변이기 때문에 불변 데이터를 같은 프로그램 외부에 건네줘도 나중에 그 값이 나 몰래 바뀌거나 내부에 영향을 주지 않는 다는 것을 확신할 수 있음
- 값 타입은 불변이므로 동시성 프로그래밍과 분산 시스템에도 유리
- 값을 복재해서 이곳저곳에서 사용해도 서로 간의 참조를 관리하지 않아도 되므로 유용
- swift언어에서는 struct라는 값 타입이 있고, 보통 데이터 구조를 표현할때 struct를 사용하고 만약 이 함수 안에서 필드의 값을 변경하려면 명시적으로 mutating을 입력이 필요
- 명시적으로 mutating을 입력하게 하는건 개발자에게 반드시 필요할때만 set하는 코드를 만들라는 의미
- 좋은 코드는 필드를 변경하는게 아닌 새로운 생성자를 사용하여 변경하는것 (= 불변성)
- 참조를 값 타입으로 변경하면 안되는 시점은?
- 값 타입이 여러 곳에서 공유하고자 하는 경우
- 항상 값타입이 좋은것은 아니고, 이에관한 내용은 다음 포스팅 글에서 값을 참조로 바꾸기에서 계속
참조를 값으로 바꾸기 예시)
- swift에서는 기본적으로 값 타입인 struct가 있으므로 struct로 예시 작성
- swift에서는 computed property를 사용하면 간편하게 getter, setter 함수가 역할을 대신 할 수 있으므로 함수대신 프로퍼티로 표현
struct TelephoneNumber {
var areaCode: String
var number: String
init(areaCode: String, number: String) {
self.areaCode = areaCode
self.number = number
}
}
struct Person {
var telephoneNumber: TelephoneNumber
var officeAreaCode: String {
get { telephoneNumber.areaCode }
set { telephoneNumber.areaCode = newValue }
}
var officeNumber: String {
get { telephoneNumber.number }
set { telephoneNumber.number = newValue }
}
}
- 문제점
- Person에서 setter 부분에 telephoneNumber.number를 바꾸고 있는 상황
- 필드를 바꾼다는 것은 불변성이 아니기 때문에 리펙토링 필요
- 리펙토링
- 1. 현재 불변성이 아닌 TelephoneNumber의 areaCode, number를 불변성으로 바꾸기
- 2. 불변성으로 바꾸고 Person의 setter에서 필드를 바꾸는게 아닌 새로운 객체를 만들도록 수정
struct Refactor_TelephoneNumber {
// 1. 불변성 프로퍼티로 변경 (var -> let)
let areaCode: String
let number: String
init(areaCode: String, number: String) {
self.areaCode = areaCode
self.number = number
}
}
struct Refactor_Person {
var telephoneNumber: Refactor_TelephoneNumber
// 2-1. setter안에 필드를 변경하는게 아닌 새로 객체를 만들도록 변경
var officeAreaCode: String {
get { telephoneNumber.areaCode }
set { telephoneNumber = .init(areaCode: telephoneNumber.areaCode, number: newValue) }
}
// 2-2. setter안에 필드를 변경하는게 아닌 새로 객체를 만들도록 변경
var officeNumber: String {
get { telephoneNumber.number }
set { telephoneNumber = .init(areaCode: newValue, number: telephoneNumber.number) }
}
}
참고) 반대 리펙토링 - 값을 참조로 바꾸기
* 전체 코드: https://github.com/JK0369/ExRefactoring8_4
* 참고
- Refactoring (Martin Flowler)
'Refactoring (리펙토링)' 카테고리의 다른 글
[Refactoring] 8-5 데이터 조작화 (값을 참조로 바꾸기) (0) | 2023.05.22 |
---|---|
[iOS - swift] Protocol 지향 프로그래밍 (상속보다 프로토콜을 사용하는게 좋은 이유, 인터페이스, DIP, SRP) (0) | 2023.05.21 |
[Refactoring] 8-3. 데이터 조작화 (파생 변수를 질의 함수로 바꾸기) (0) | 2023.05.14 |
[Refactoring] 8-1. 데이터 조작화 (변수 쪼개기) (0) | 2023.05.12 |
[Refactoring] 7-8. 기능 이동 (함수 이동, 중첩함수 제거, 모듈성) - 반복문을 파이프라인으로 바꾸기, 선언형 프로그래밍 (0) | 2023.04.28 |
Comments