Skip to content

Latest commit

 

History

History
166 lines (107 loc) · 8.8 KB

API Design Guidelines.md

File metadata and controls

166 lines (107 loc) · 8.8 KB

API 디자인 가이드라인

1. 기본개념

  • 사용할 때 기준으로 명확하게 작성하는 게 가장 중요하다. 메소드나 속성과 같은 개체들은 한 번만 선언하고 반복적으로 사용한다. API를 만들 때는 이러한 개체들을 이해하기 쉽고 간결하게 만드는데 중점을 주고 작성해야 한다. 사용하는 상황에서 문맥상 명확하게 이해도록 하자.

  • 명확한 표현이 압축한 간결성보다 더 중요하다. 스위프트 코드는 간결하게 작성할 수 있지만, 단지 글자수를 줄여서 가장 짧은 코드를 만드는 게 목표는 아니다. 스위프트 코드의 간결성은 자연스럽게 반복적으로 재사용하는 코드(boilerplate)를 줄이는 기능과 강한 타입 시스템의 부수효과로 드러날 뿐이다.

  • 모든 선언 부분에 주석을 적극적으로 작성하라. 문서를 작성하면서 얻는 통찰력은 API 설계에 큰 영향을 줄 수 있으니 미루지 말고 주석을 꼭 달자. 간단한 용어로 API 기능을 설명하지 못한다면, 설계의 문제가 있을 가능성이 높다.


2. 이름 짓기(Naming)

명확한 사용법 제시하기

  • 그 이름을 사용하는 부분의 코드를 읽는 사람에게 혼란을 줄 수 있는 단어는 피한다.

  • 불필요한 단어는 생략한다.

    이름의 모든 단어는 사용자 관점에서 주요한 정보를 제공해야만 한다.

  • 변수, 매개변수, 연관 타입은 선언한 타입이나 제약사항 보다는 역할에 맞는 이름을 갖도록 한다.**

  • 매개변수 역할을 명확하게 넣어서 부족한 타입 정보를 보완한다.

말하는 것처럼 술술 써지도록 작성하기

  • 메소드나 함수를 사용할 때 영어 문장을 작성하는 것처럼 느끼도록 제공한다.

  • 팩토리 메소드 이름은 "make"로 시작한다. 예) x.makeIterator()

  • 초기화(생성) 메소드나 팩토리 메소드는 첫 번째 인자에 추가적인 설명을 포함하지 않도록 한다. 예) x.makeWidget(cogCount: 47)

  • 함수나 메소드 이름은 사이드 이펙트(side-effects)에 따라 다르게 정한다

    • 사이드 이펙트가 없는 경우는 명사형으로 작성한다. 예) x.distance(to: y), i.successor().

    • 사이드 이펙트가 있는 경우에는 명령형 동사로 작성한다. 예) print(x), x.sort(), x.append(y).

    • 가변/불변 메소드 이름을 함께 고려해야 한다.

    • 동사로 표현하면 자연스럽게 "ed"나 "ing"를 붙여서 불변 메소드 이름을 만들 수 있다.

    가변(Mutating) x.sort(), x.append(y)

    불변(Nonmutating) z = x.sorted(), z = x.appending(y)

    • 동작을 명사로 표현하기 적합한 경우에는 가변 메소드 이름에 "form-"을 머릿말로 붙인다.

    불변 x = y.union(z), j = c.successor(i)

    가변 y.formUnion(z), c.formSuccessor(&i)

  • 불변으로 사용할 때 Boolean 메소드나 프로퍼티를 사용할 때는 리턴값을 받아서 단언 구문(Assertion)처럼 읽도록 한다. 예) x.isEmpty, line1.intersects(line2).

  • 무언가를 설명하는 프로토콜은 명사로 읽어야 한다. 예) Collection

  • 기능이나 가능성을 표현하는 프로토콜은 -able, -ible, -ing 등을 붙여서 표현한다. 예) Equatable, ProgressReporting.

  • 그 외에 상수, 변수, 속성, 타입들은 명사로 읽어야 한다.

용어를 잘 표현하기

  • 애매한 용어를 피한다. '피부(skin)'를 '표피(epidermis)'라고 하지말고, 더 쉽게 의미를 전달할 수 있는 표현이 있으면 그걸 선택하라. 전문 용어(Term of Art)는 필수적인 소통 도구지만, 사용하지 않을 경우 놓칠 수 있는 중요한 의미를 꼭 표현해야 하는 경우만 사용하세요.

  • 전문 용어를 사용한다면 기존 의미에 맞춰 사용한다. 일반적인 용어가 애매하거나 불명확한 것을 정확하게 표현하기 위해서만 기술적인 용어를 사용하는 것이 좋다.

    • 전문가를 놀라게 하지마라: 기존에 친숙하게 사용하던 용어에 전혀 새로운 의미를 부여한다면 선배들이 놀라거나 화를 낼지도 모른다.
    • 초보자를 헷갈리게 하지마라: 웹에서 용어를 찾아 공부하는 사람들에게도 용어의 전형적인 의미가 중요하다.
  • 축약어를 피한다. 전문 용어면서 표준 형태가 아닌 약자는 잘못 풀어쓰거나 오해를 할 수 있다.

  • 선례를 받아들인다. 모든 초보자를 위해 용어를 적지 말고 기존 문화에서 쓰이는 용어가 적합하다.


3. 규칙(Conventions)

✳️기본 명명 규칙(중요)✳️

  • 변수, 상수, 함수, 메서드, 타입 등의 이름은 유니코드에서 지원하는 어떤 문자(한글, 한자, 영문, 숫자, 이모티콘 등)라도 사용할 수 있다.

    다만 다음과 같은 예외 경우는 사용할 수 없다.

    • 스위프트에서 미리 정한 예약어 또는 키워드
    • 해당 코드 범위 내에서 미리 사용되는 기존 이름과 동일한 이름
    • 연산자로 사용될 수 있는 기호(+,-,*,/)
    • 숫자로 시작하는 이름
    • 공백이 포함된 이름
  • 대소문자 표기법을 따른다.

    1. 함수, 메서드, 인스턴스 이름은 첫 글자를 소문자로 사용하는 LowerCamelCase를 사용한다.
    2. 클래스, 구조체, 익스텐션, 프로토콜, 열거형(enum) 이름은 타입의 이름이기 때문에 첫 글자를 대문자로 사용하는 UpperCamelCase로 표기한다.
    3. 명령 구문 뒤에 세미콜론(;)을 붙이는 것은 선택 사항이다. (But, 굳이 붙이지 말 것)
    4. 대소문자를 구분하므로 유의한다. (Var와 var를 다르게 인식함.)
  • O(1) 복잡도가 아닌 연산 프로퍼티(Computed Property)는 설명을 만든다. 대부분 사람들은 저장 프로퍼티에 익숙해서 프로퍼티 값에 접근하지 않는다고 생각하는데, 생각이 어긋날 수 있을 때 경고해야 한다.

  • 소속이 없는 자유로운 함수를 만들기 보다는 메소드나 속성을 만든다. 다음의 특별한 경우에만 함수를 고려하라.

    1. 명확하게 self가 없을 때 : min(x,y,z)
    2. 제약없는 제네릭 함수인 경우 : print(x)
    3. 함수 표현이 특정한 도메인 표기법을 준수하는 경우 : sin(x)
  • 메소드가 같은 의미를 갖고 있거나 특정한 도메인 영역에서만 동작을 하는 경우에는 기본 이름을 공유할 수 있다.

매개 변수

func move(from start: Point, to end: Point)

  • 문서화 할 수 있는 매개 변수 이름을 선택한다. 함수나 메소드를 사용할 때 매개변수가 감춰져있더라도 여전히 중요한 역할을 한다.

  • 매개변수 기본값을 지정해서 편리함을 더한다. 매개 변수에 흔히 넘기는 값 자체를 기본값으로 활용하라.

  • 기본 인자값은 매개 변수 목록에서 마지막 위치부터 넣는다. 기본 인자값이 없는 매개변수는 메소드에서 더 중요한 역할을 하고, 메소드를 호출하는 곳에서 안정적으로 초기화하는 형태로 사용할 수 있다.

인자 레이블

func move(from start: Point, to end: Point) x.move(from: x, to: y)

  • 레이블이 인자값을 구분하는데 도움이 안되면 모든 레이블을 생략한다. 예) min(number1, number2), zip(sequence1, sequence2)

  • 초기화 생성 함수(이니셜라이저)에서 다른 타입 값을 받아서 변환하고 보관하는 (값보존 변환) 경우에는 첫 번째 인자 레이블을 생략한다. 예) Int64(someUInt32)

  • 첫 번째 인자값이 (영어에서) 전치사 형태라면 인자값 레이블을 표기한다.

  • 첫 번째 인자값이 (전치사가 아니라) 다른 문법상의 구문이라면 레이블은 생략하고, x.addSubview(y)처럼 기본 이름에 의미있는 단어를 뒤에 붙여도 된다.

  • 그 외에 모든 경우는 레이블을 표기하라.


4. 특별 지침

  • 튜플 멤버에 레이블을, 클로저 매개변수에 이름을 표기하라.

  • AnyAnyObject, 제약없는 제네릭 매개변수처럼 제약없는 다형성(polymorphism)은 오버로드할 때 혼동하지 않도록 주의하라.



참고 자료

API Design Guidelines

Introduction to Coding Guidelines for Cocoa

스위프트 API 가이드라인