2023. 12. 14. 17:24ㆍApple/Swift
1. fundamental(기초)
사용 시점의 명확성(Clarity as the point of use) -> 가장 중요한 목표
- 메소드, 속성(property) 등의 엔터티는 한 번만 선언되지만 반복적으로 사용
=> API를 명확하고 간결하게 사용하도록 설계해라!
=> 설계를 평가할 때, 선언문(declaration)을 읽는 것만으로는 충분치 않다. 항상 사용 사례를 조사해 맥락해서 명확하게 보이는지 확인해라!
간결함보다 명확성이 더 중요해!
Swift 코드는 간결할 수 있으나, 최소한의 문자로 가능한 가장 간단한 코드를 구현하는 게 목표가 아니다. Swift 코드의 간결함은 강력한 유형 시스템과 자연스럽게 상용구(boilerplate)를 줄이는 기능의 부작용이다.
BoilerPlate란?
- 다양한 프로그래밍 언어 및 애플리케이션에서 코딩 효율성과 품질을 개선하는 데 사용할 수 있는 코드 섹션을 말한다!
- 최소한의 변경으로 여러 곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드
보일러플레이트 코드 줄이기!- 내 의견: 리팩토링을 할때 남발된 보일러플레이트도 산발적으로 분산된 곳에서 일일이 수정해줘야한다. 그걸 따로 빼두는 작업, 분리하는 작업을 하는게 좋긴 할 것 같다.
모든 선언(declaration)에 대해 코멘트(주석)를 작성하라
문서 작성을 통해 얻은 통찰력은 설계(디자인)에 큰 영향을 미칠 수 있으므로, 미루지 마라!
2. Naming(명명)
명확한 사용 권장
- 이름이 사용된 코드를 읽는 사람의 모호함을 피하기 위해 필요한 모든 단어를 포함
권장 예
extension List {
public mutating func remove(at position: Index) -> Element
}
employees.remove(at: x)
나쁜 예
employees.remove(x)
메소드 시그니쳐에서 at 이라는 매개변수명을 생략한다면 제거할 요소의 위치를 나타내기 위해 x를 사용하는 대신 메소드 x와 동일한 요소를 검색하고 제거한다는 것을 독자에게 암시하는 오류를 범할 수 있다!
불필요한 말은 생략해라
이름의 모든 단어는 사용 장소에서 중요한 정보를 전달한다.
- 의도를 명확히 하거나 의미를 명확하게 하기 위해 더 많은 단어가 필요할 수 있지만, 독자가 이미 알고 있는 정보, 중복되는 단어는 생략해야 한다. 특히, 타입 정보만 반복하는 단어는 생략해라.
나쁜 예
public mutating func removeElement(_ member: Element) -> Element?
allViews.removeElement(cancelButton)
권장 예
public mutating func remove(_ member: Element) -> Element?
allViews.remove(cancelButton)
이미 전달 인자나 반환타입에서 Element 가 제거된다는 걸 명시했기에 굳이 메소드명까지 Element 를 붙일 필요는 없다는 의미인 것 같다.
→ 때때로 모호함을 피하기 위해 타입 정보를 반복해야하지만, 일반적으로 매개변수의 타입보다는 매개변수의 역할을 설명하는 단어를 사용하는 것이 더 좋다!
타입 제약이 아닌 역할에 따른 변수, 매개변수 및 관련 타입의 이름을 지정한다.
나쁜 예
var string = "안녕"
protocol ViewController {
associatedtype ViewType: View
}
class ProductionLine {
func restock(from widgetFactory: WidgetFactory)
}
타입 이름을 다른 용도로 사용하면 명확성과 표현력이 최적화되지 않는다.
변수명을 string, ViewType, 매개변수명을 widgetFactory 라고 칭하는 것
권장 예
var greeting = "Bonjour"
protocol ViewController {
associatedtype ContentView: View
}
class ProductionLine {
func restock(from supplier: WidgetFactory)
}
연관된 타입이 프로토콜 제약 조건에 너무 밀접하게 바인딩되어 프로토콜 이름이 역할이 되는 Protocol 경우 프로토콜 이름에 추가해 충돌을 피하라
protocol Sequence {
associatedtype Iterator: IteratorProtocol
}
protocol IteratorProtocol { ... }
매개변수의 역할을 명확히 하기 위해 weak 타입 정보를 보완한다.
특히, 매개변수 타입이 NSObject, Any, AnyObject 이거나 Int, String 같은 기본 타입인 경우 사용 시점의 타입 정보 및 문맥적의도를 완전히 전달하지 못할 수 있음. 선언은 명확하지만 사용 위치는 모호하다.
나쁜 예
func add(_ observer: NSObject, for keyPath: String)
grid.add(self, for: graphics) // 모호함
권장 예
func addObserver(_ observer: NSObject, forKeyPath path: String)
grid.addObserver(self, forKeyPath: graphics) // 명확함
참고
part 로 나눠서 정리하면서 올려봐야 겠다. 차츰 코드 예제도 내가 짜면서 익혀보면 더 도움이 되지 않을까 싶다.
'Apple > Swift' 카테고리의 다른 글
[ 이메일 유효성 체크 ] - 이메일 가입이 아무거나 다된다고? (1) (0) | 2024.08.07 |
---|---|
동시성(Concurrency)을 대하는 Swift 의 자세 1 - DispatchQueue (0) | 2024.02.02 |
Macro 에 대해서 알아보자. ( 수정중 ) (0) | 2023.11.12 |
[ 구조체와 클래스 ] (0) | 2022.12.02 |
[Swift ] Escape Sequence - 문자열처리 (0) | 2022.05.21 |