일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Xcode
- Observable
- 애니메이션
- 클린 코드
- swiftUI
- Protocol
- ios
- uitableview
- swift documentation
- 리팩토링
- UICollectionView
- map
- rxswift
- clean architecture
- tableView
- SWIFT
- HIG
- ribs
- Refactoring
- 리펙터링
- 스위프트
- Human interface guide
- MVVM
- combine
- Clean Code
- uiscrollview
- RxCocoa
- collectionview
- UITextView
- 리펙토링
- Today
- Total
목록리펙터링 (12)
김종권의 iOS 앱 개발 알아가기
용어 *메서드: 객체가 가지고 있는 하나의 행위 *함수: 객체없이 단독으로 있는 하나의 기능 (* 이 글에서는 편의상 메서드도 함수로 지칭) 함수의 파라미터 리펙토링 함수의 정의는 하나의 일을 하는 기능 단위로 볼 수 있다는 것은 유명한 의미 하지만 함수에서 인수와 파라미터를 사용할 땐 그저 함수 안에서 필요한 것을 넣는 경우가 존재 가장 위험한 코드는 함수 파라미터에 또 다른 struct나 class타입을 넣는 것 ex) 주식 정보 제공 앱을 만들 때, Candle이라는 구조체를 사용하는 경우 calculateMiPriceString 함수에서 candle 인스턴스를 받아서 candle안의 메서드를 호출하여 특정 문자열을 가져오는 함수 import UIKit struct Candle { var open:..
서브 클래스를 델리게이트로 바꾸기 특정 타입에 따라 동작이 달라지는 경우, 주로 enum case로 분기하여 구현하지만 저번시간에 알아본대로(이전 글 참고) 상속 관계를 만들면 SRP를 지키면서 더욱 유지보수 하기 쉽게 코드 관리가 가능 공통 코드는 수퍼클래스가 책임지고, 각각의 기능은 서브클래스로 정의하여 각 하나의 역할을 담당하도록 구현하는 것 이처럼 서브 클래스의 장점도 많지만, 단점이 존재 단점1) 수퍼클래스와 서브클래스간의 결합도가 증가하여 부모를 수정하면 자식들의 기능을 헤칠 수 있음 단점2) 사람 객체의 동작이 나이대와 소득 수준으로 나뉜다면, 서브클래스를 부자와 서민으로 나눌 것인데 이렇게 된다면 각 서브클래스에서 하나의 인스턴스로 두 기능 모두 사용이 불가능한 상태 서브 클래스를 델리게이..
케이스를 서브클래스로 바꾸기 특정 타입에 따라서 기능을 달리해야하는 경우 보통 enum case로 타입을 구분하고 하나의 파일에서 분기를 넣는데, 이렇게되면 하나의 역할에 대해서만 책임 (Single Responsibility Prinsiple, SRP)을 지키지 못하는 코드로 변동 SRP를 지키지 못하면 type에 대한 특정 동작이 하나의 파일에 섞여나게되어, type에 대한 기능이 수정되어야 할 때 특정 type과 관련없는 코드가 변경될 우려가 존재 변경사항에 대해 코드를 수정해야하는 개발자 입장에서는 변경하려는 type 외에도 다른 type들도 고려하게되어 수정하기가 쉽지 않게 유지 SRP를 지키도록 type으로 하나의 파일에 여러개의 역할에 대해 구분할 때, 서브 클래스로 만들면 유지보수에 용이 ..
메서드 올리기 서브클래스들이 여러개 있을 때 이 클래스에서 동일한 내용을 정의하는 메서드가 있을 때 이 메서드를 수퍼클래스에 이동시켜서 중복을 제거할 수 있음 중복의 위험) 동일한 로직을 사용하고 있는 중복 코드에서, 한쪽의 변경이 다른 쪽에는 반영이 안되는 이슈가 발생할 수 있는 가능성 존재 예시) 메서드 올리기 Member라는 수퍼 클래스가 있고 서브 클래스로 Developer, FireFighter가 존재 얼핏보면 메서드 이름이 달라서 다른 메서드인것 같지만 같은 역할을 하는 것이므로 getFullname(), getName()을 하나로하여 수퍼 클래스로 이동이 필요 class Member { var age: Int var name: String init(age: Int, name: String) ..
오류 코드를 예외로 바꾸기 하드코딩된 상수인 매직 넘버를 사용하여 오류처리를 하는 경우가 있는데, 매직 넘버를 사용하면 의미나 목적을 이해할 수 없으므로 매직 넘버를 사용하면 안좋고 예외로 바꾸어야함 ex) 매직 넘버 예시 // 매직 넘버를 사용한 예시 func calculateAreaOfCircle(radius: Double) -> Double { return 3.14159 * radius * radius } // 매직 넘버를 상수로 대체 let pi = 3.14159 func calculateAreaOfCircle(radius: Double) -> Double { return pi * radius * radius } ex) 예외 처리를 하지 않은 오류 enum FetchItemType: CaseIte..
수정된 값 반환하기 메소드 내부에서 값을 변경하는 것보다는, 메소드에서 값을 계산하여 나온 반환 값을 사용하는 편이 좋은 코드 데이터가 어떻게 수정되는지를 추적하는 일은 코드에서 이해하기 어려운 요소이므로, 함수 내부에서 데이터 값을 수정하는 예측하기 힘든 것들을 리펙토링해야함 즉 예측하기 쉬운 프로그래밍은 함수를 호출하는 쪽에서 어떤 값이 변경되는지 쉽게 파악이 가능해야하며 이는 함수 내부에서 전역 변수의 값을 바꾸는 것을 지양해야함 리펙토링 예시 main() 메소드가 호출될때, 이 안에서 calculateAsset()이 호출되는데 함수 내부에서 전역 변수인 total을 바꾸게 되어 사용하는 쪽 main 안에만 보면 total 값이 바뀌는지 예측하기가 힘듦 struct Asset { var countO..
cf) 파생과 질의 구분하기 파생(Derived) 변수: 사용하는쪽에서 관심 밖의 변수들에도 영향을 주는 것 질의(Query) 함수: 사용하는쪽에서 관심 대상인 변수에만 영향을 주는 것 (단순 get, set) 매개변수를 질의 함수로 바꾸기 함수의 동작에 변화를 주는 요인은 함수의 매개변수 즉, 함수의 동작에 변화를 주는 요인을 구성할 때 짧으면 짧을수록 이해하기가 쉬운 형태의 함수 함수가 스스로 쉽게 결정할 수 있는 값을 매개변수로 건네는 것도 일종의 중복이므로, 이 결정은 함수안에서 결정하게하여 더욱 간결한 함수형태로 변경이 필요 ex) 함수를 사용하는 쪽에서 person, person.name을 넘기는데, 중복코드가 발생 let person = Person(age: 1, name: "jake") l..
공통 모델이 있을 때 리펙토링 방법 보통 공통 모델에서 특정 프로퍼티만 필요한 경우, 따로 DTO를 만들어서 convert 로직을 만드는데, protocol을 활용하면 간결하게 해결이 가능 ex) 공통 모델 CommonModel이 있고, 각 모델에서 필요한 모델도 각각 있어서 convert해서 쓰는 패턴 공통 모델이 CommonModel처럼 있는 경우 struct CommonModel { let age: Int var name: String let date: String let visited: Bool let imageData: Data var message: String } VC2, VC3에서 필요한 모델이 있어서 struct로 만들고 이걸 CommonModel에서 convert해서 쓰는 방식 stru..