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 |
Tags
- 클린 코드
- Observable
- 리펙토링
- combine
- ribs
- collectionview
- 스위프트
- uitableview
- Xcode
- HIG
- Human interface guide
- UICollectionView
- SWIFT
- uiscrollview
- MVVM
- Refactoring
- Clean Code
- 리펙터링
- tableView
- clean architecture
- 리팩토링
- Protocol
- swift documentation
- 애니메이션
- UITextView
- swiftUI
- map
- ios
- rxswift
- RxCocoa
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[Refactoring] 5-3. 기본적인 리펙토링 (여러 함수를 하나의 함수로 묶기) 본문
리펙토링 핵심
- 각 방법들을 '왜' 수행해야 하는지 깨닫고 유연하게 적용하기
함수들을 클래스로 묶기
- 함수는 데이터를 입력받아서 여러가지 정보를 얻는데, 이렇게 입력받는 데이터들의 중복을 줄이기 위한 방법
- 매개변수 같은 중심(공통 데이터)으로 긴밀하게 엮여 작동하는 함수 무리를 하나의 함수로 묶는 것
- 장점 - 중복코드를 막고 함수들이 공유하는 공통 환경을 더욱 명확하게 표현이 가능
ex) 여러 함수를 묶기
- 보일러 사용량과 기간에 대해 세금을 계산하는 코드
// 보일러 사용 정보
struct UseInfo {
let quantity = 1
let month = 2
let year = 3
}
// 보일러 정보 획득
func getUseInfo() -> UseInfo {
UseInfo()
}
// 기본적으로 내야하는 비율
func baseRate(month: Int, year: Int) -> Int {
month + year
}
// 세금의 최댓값
func taxThreshold(year: Int) -> Int {
year * 3
}
- a 고객의 세금 계산
- 문제점: baseRate를 구할때 month, year 모두 aUserInfo 하나만 받으면 내부에서 .month, .year 접근해서 사용 가능하므로 파라미터를 하나만 받도록 수정해도 처리가 가능
let aUserInfo = getUseInfo()
let aBaseCharge = baseRate(month: aUserInfo.month, year: aUserInfo.year) * aUserInfo.quantity
let aTexableCharge = max(0, bBaseCharge - taxThreshold(year: 2023))
- calculateBaseCharge(userInfo:) 를 만들어서 리펙토링
func calculateBaseCharge(useInfo: UseInfo) -> Int {
baseRate(month: useInfo.month, year: useInfo.year)
}
let bUseInfo = getUseInfo()
let bBaseCharge = calculateBaseCharge(useInfo: aUseInfo) * bUseInfo.quantity
let bTexableCharge = max(0, bBaseCharge - taxThreshold(year: 2023))
- 하나의 함수로 묶어서, 사용하는 쪽(=클라이언트 코드)에서는 단순히 useInfo와 year만 넣으면 되도록 구현
func calculateTotalCharge(useInfo: UseInfo, year: Int) -> Int {
let baseCharge = calculateBaseCharge(useInfo: useInfo)
let textableCharge = max(0, baseCharge, taxThreshold(year: year))
return textableCharge
}
let cTexableCharge = calculateTotalCharge(useInfo: getUseInfo(), year: 2023)
- 결과
- 중복 제거 - 리펙토링전에 클라이언트 코드에서 baseCharge와 textableCharge를 계산하는 코드가 a 클라이언트 코드, b 클라이언트 코드가 생성되지만 리펙토링 후에는 이런 중복 작업이 불필요
- 주의
- 파라미터의 데이터들이 중복으로 생길때 함수로 묶을수도 있지만, 원본 데이터가 코드 안에서 갱신될때는 함수가 아닌 클래스로 묶을 것 (상태가 변경된다는 것은 함수가 아닌 인스턴스의 성격을 갖는 클래스로 묶는것이 더욱 적합)
- * 클래스는 상태(state)와 동작(method)로 이루어져 있기 때문에 상태를 변경할땐 이러한 인스턴스로 관리하는게 논리적으로 더욱 코드를 읽는 입장에서 예측하기 쉬움
* 참고
- Refactoring (Marting Flowler)
'Refactoring (리펙토링)' 카테고리의 다른 글
[Refactoring] 6-1. 캡슐화 (레코드 캡슐화하기) (2) | 2023.03.21 |
---|---|
[Refactoring] 5-4. 기본적인 리펙토링 (단계 쪼개기) (0) | 2023.03.20 |
[Refactoring] 5-2. 기본적인 리펙토링 (변수 추출하기, 변수 인라인하기) (0) | 2023.03.18 |
[Refactoring] 5-1. 기본적인 리펙토링 (함수 추출하기, 함수 인라인하기) (0) | 2023.03.07 |
[Refactoring] 4. 테스트 구축하기 (테스트 코드가 중요한 이유) (0) | 2023.01.19 |
Comments