Swift 기본 가이드라인 - part 1

2023. 12. 14. 17:24Mobile/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) // 명확함

 

 

참고 

https://swift.org 

 

Swift.org

Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.

www.swift.org

 

 

part 로 나눠서 정리하면서 올려봐야 겠다. 차츰 코드 예제도 내가 짜면서 익혀보면 더 도움이 되지 않을까 싶다.