일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- HIG
- RxCocoa
- ribs
- 리팩토링
- tableView
- Human interface guide
- 리펙토링
- clean architecture
- UICollectionView
- uiscrollview
- map
- 클린 코드
- MVVM
- swift documentation
- SWIFT
- 리펙터링
- Observable
- Clean Code
- UITextView
- 애니메이션
- collectionview
- combine
- 스위프트
- Protocol
- Refactoring
- swiftUI
- Xcode
- ios
- uitableview
- rxswift
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] Clean Code(클린 코드) - 3. 함수 (1) 본문
함수
- 가능한 하나의 함수는 20줄도 길다고 생각하여, 짧게 만드는것이 가독성에 중요한 요소
- 하나의 함수가 길어진다면, 그 길어지는 것들을 또다른 함수로 정의하여 그것을 호출하도록 설계
- 함수 안의 if, guard문의 블록은 여러줄이 아닌 한줄로 구현
- 하나의 함수는 한가지의 일만 하도록 구현
ex) 페이지를 입력받아서 HTML로 변환하는 함수 정의
- 입력받은 페이지가 테스트 페이지인 경우, 설정페이지(setup)와 해제페이지(teardown)에 페이지를 넣고 해당 테스트 페이지를 HTML로 렌더링하는 기능
WRONG
- if문 블록이 한줄을 넘어가므로 잘못된 코드
- 하나의 함수에서 다양한 일 처리 (페이지를 가져오고, 설정페이지와 해제페이지를 추가하는 작업)
func renderPageWithSetupsAndTeardowns(_ page: Page) -> String {
let isTestPage = page.contains("Test")
if isTestPage {
let testPage = page.getWikiPage()
var newPageContent = PageContent()
includeSetup(newPageContent, to: testPage)
newPageContent.append(page.getContent())
includeTeardown(newPageContent, to: testPage)
page.setContent(newPageContent)
}
return page.getHtml()
}
RIGHT
- if문 블록 안을 한줄로 유지
- 하나의 함수에서 하나의 일만 처리 (설정페이지와 해제페이지를 테스트페이지에 넣는 작업)
func renderPageWithSetupsAndTeardowns(_ page: Page) -> String {
if isTestPage(page) {
includeSetupAndTeardownPages(to: page)
}
return page.getHtml()
}
하나의 함수는 하나의 일만 해야한다는 원칙
- 하나의 함수에서 한가지의 일만 한다는 정확한 의미
- `함수의 이름`아래에서 추상화 수준이 하나라는 의미
- 위 리펙토링된 코드도 어떻게보면 3가지의 일을 하고 있는 것(테스트 페이지인지 확인, 페이지 삽입, HTML로 렌더링)이지만, 함수 이름 아래에 추상화 수준에서 볼땐 일이 하나인 상태
- 함수 하나당 추상화 수준은 하나로 유지할 것
- 함수가 확실히 한 가지 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 가능
- 추상화 수준이 섞이게 되면 코드를 읽는 사람이 헷갈리고, 코드가 추가될 때 깨어진 창문처럼 점점 더럽혀지는 코드로 변화
- 위 코드에서는 추상화 수준이 하나로 유지되지 않은 형태 - getHeml()은 추상화 수준이 높고, append("\n")은 추상화가 낮은 수준
func someFunc(_ page: Page) -> String {
var testPage = page.getWikiPage()
testPage.append("\n") // 추상화 수준이 낮은 편
return page.getHtml() // 추상화 수준이 높은 편
}
Switch 문
- switch 문에서 가장 주의해야 하는 점
- switch문은 애초부터 키워드가 많이 존재하므로 (switch, case) 작게 만들기 힘든 점
- switch문은 N가지를 처리하므로 한 가지 작업만 하는 switch문을 만들기 어려운 점
- 위와같은 문제를 해결하기 위해서, 저차원 클래스에 숨기고 다형성을 이용
WRONG
- 함수가 긴 문제, 만약 새 직원 유형이 추가되면 더 길어지는 현상
- 한 가지 작업만 수행하지 않는 점
- 하나의 actor에 대해서 책임지는 함수가 아니므로, 코드를 변경할 이유가 여러가지 될것이므로 SRP를 위반
- 새 직원 유형을 추가할 때마다 코드를 변경해야하기 때문에 OCP위반
- 아래 함수와 동일한 구조의 함수가 여러개 생길 가능선 존재 ... isPayday(employee:date:), deliverPay(employee:pay:)
func calculatePay(_ employee: Employee) -> Money throws InvalidEmplyeeType {
switch employee {
case .commissioned:
return calculateCommissionedPay(employee)
case .hourly:
return calculateHourlyPay(employee)
case .salaried:
return calculateSalariedPay(employee)
default:
return InvalidImployeeType(employee.type)
}
}
RIGHT
- switch문을 사용하긴 하는데, 외부에서는 interface를 통해 접근하도록 추상화하여, 사용하는쪽에서는 switch의 존재를 모르게하여 외부에 따라 switch에 변경이 생기지 않도록 설계
- 론 제프리스(Ron Jeffries)의 3가지 원칙(중복 줄이기, 표현력 높이기, 초반부터 추상화 고려) 중에 추상화를 고려하면 생기는 장점
protocol Employee {
var isPayday: Bool { get }
func calculatePay() -> Money
func deliverPay(pay: Money)
}
protocol EmployeeFactory {
func makeEmployee(employeeRecord: EmployeeRecord) throws -> Employee
}
class EmplyFactoryImpl: EmployeeFactory {
func makeEmployee(employeeRecord: EmployeeRecord) throws -> Employee {
switch employeeRecord {
case .commissioned:
return CommissionedEmployee(employeeRecord)
case .hourly:
return HourlyEmployee(employeeRecord)
case .salaried:
return SalariedEmployee(employeeRecord)
default:
throw InvalidImployeeTypeError(employee.type)
}
}
}
* 참고: Clean Code (로버트 C. 마틴)
'Clean Code (클린 코드)' 카테고리의 다른 글
[iOS - swift] Clean Code(클린 코드) - 5. 객체와 자료 구조 (객체지향, 절차지향 장단점) (0) | 2021.11.17 |
---|---|
[iOS - swift] Clean Code(클린 코드) - 4. 주석 (0) | 2021.11.14 |
[iOS - swift] Clean Code(클린 코드) - 3. 함수 (2) (0) | 2021.11.13 |
[iOS - swift] Clean Code(클린 코드) - 2. 의미 있는 이름 (0) | 2021.11.10 |
[iOS - swift] Clean Code(클린 코드) - 1. 클린 코드의 개념 (0) | 2021.11.10 |