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
- 리팩토링
- SWIFT
- MVVM
- Human interface guide
- combine
- 리펙토링
- HIG
- ios
- uiscrollview
- map
- Observable
- swiftUI
- 애니메이션
- Clean Code
- clean architecture
- RxCocoa
- rxswift
- 스위프트
- Protocol
- collectionview
- Xcode
- Refactoring
- tableView
- UITextView
- swift documentation
- 클린 코드
- 리펙터링
- UICollectionView
- ribs
- uitableview
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] Clean Code(클린 코드) - 6. 오류 처리 본문
오류 코드보다 예외를 지향
- 예외처리는 논리가 들어간 로직부분과 예외를 처리하는 부분을 나누어서 코드가 섞이지 않게되어 복잡해지지 않게되는 장점이 존재
- 오류 코드는 테스트가 힘들지만, 예외를 사용하면 throw에 관한 리턴값을 확인할 수 있어서 TDD에도 용이
WRONG
class DeviceController {
func sendShutDown() -> Void {
if handle != DevcieHandle.INVALID {
if record.getStatus() != DEVICE_SUSPENDED {
pauseDevice(handle)
clearDeviceWorkQueue(handle)
closeDevice(handle)
} else {
Log.error("Device suspended. Unable to shut down")
}
} else {
Log.error("Invalid handle")
}
}
}
RIGHT
class DeviceController {
func sendShutDown() -> Void {
do {
try shutDown()
} catch {
Log.error(error)
}
}
private func shutDown() throws {
let handle = getHandle(DEV1)
let record = retrieveDeviceRecord(handle)
do {
try pauseDevice(handle)
try clearDeviceWorkQueue(handle)
try closeDevice(handle)
} catch {
...
throw ...
}
}
private getHandle(id: DeviceId) -> DeviceHandle {
...
throw DeviceShutDownError.error1
...
}
...
}
예외에 의미를 제공할 것
- 예외를 던질 때는 전후 상황을 충분히 덧붙여서 예외를 이해하기 쉽도록 설계
- 자바는 모든 예외에 호출 스택을 제공하지만, 실패한 코드의 의도를 파악하려면 호출 스택만으로는 부족
- 실패한 연산 이름, 실패 유형 등을 같이 제공하도록 설계 필요
여러가지 유형의 예외가 있는 경우, Wrapper 클래스 사용
- 여러가지 유형의 예외처리가 필요한 경우, Wrapper클래스를 만들어서 간결화
ex) 여러가지 유형의 예외처리가 나열된 경우
let port = ACMEPort(12)
do {
try port.open()
} catch DataException.DeviceResponse {
reportPortError(error)
Log.error("Device response exeception", error)
} catch DataException.ATM1212UnlockedException {
reportPortError(error)
Log.error("Unlock exception", error)
} catch DataException.GMXError {
reportPortError(error)
Log.error("Device response exception")
}
> LocalPort Wrapper 클래스를 만들어서 처리
- 장점1: 해당 모듈을 사용할 때 해당 모듈의 오류들을 다양하게 알지 않아도 되므로 의존성이 줄어드는 장점
- 장점2: 의존성이 줄어들었으므로, 사용하는 입장에서 다른 모듈로 변경에도 용이
class LocalPort {
private innerPort: ACMEPort
init(innerPort: ACMEPort) {
self.innerPort = innerPort
}
func open() {
do {
try port.open()
} catch DataException.DeviceResponse {
throw portDeviceFailure(error)
} catch DataException.ATM1212UnlockedException {
throw portDeviceFailure(error)
} catch DataException.GMXError {
throw portDeviceFailure(error)
}
}
}
let port = LocalPort(12)
do {
try port.open()
} catch DataError.PortDeviceFailure {
reportError(error)
Log.error(error)
}
nil을 반환하는 코드는 지양할 것
- 모듈에서는 가급적 nil을 반환하지 않고 non-optional값을 반환할 것
- 모듈에서 nil을 반환하게 된다면, 호출자에게 문제를 떠넘기는 형태 (아래 예시)
func registerItem(item: Item) {
if item != nil {
let registry = peristentStore.getItemReistry()
if registry != nil {
let existing = registry.getItem(item.getID())
if existing.getBillingPeriod().hasRetailOwner() {
existing.register(item)
}
}
}
}
* 참고: Clean Code (로버트 C. 마틴)
'Clean Code (클린 코드)' 카테고리의 다른 글
[iOS - swift] Clean Code(클린 코드) - 8. Unit Test (단위 테스트) (0) | 2021.11.19 |
---|---|
[iOS - swift] Clean Code(클린 코드) - 7. 소프트웨어의 경계 (0) | 2021.11.18 |
[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 |
Comments