Swift API Design Guidelinesの紹介(Swift 3版)

[Swift.org - API Design Guidelines](https://swift.org/documentation/api-design-guidelines/#write-doc-comment)を読みながら日本語で書き起こしてみました。
(全訳では無く、また一部意訳など混ざっています。)

API Design Gudelinesということで、例えばアプリ実装の特に画面側のコード書く際にはあまり気にしなくても良い気がするものも少し混ざっている気がしました。

原文に豊富にあるコード例はほとんど省いたので、適宜原文見た方が分かりやすいかと思います。

# [基本](https://swift.org/documentation/api-design-guidelines/#fundamentals)

## [用途が明確なこと](https://swift.org/documentation/api-design-guidelines/#clarity-at-the-point-of-use)

用途が明確なことは、最も重要なゴール。コードは書かれるより読まれることの方がずっと多い。

## [明確さは簡潔さより重要](https://swift.org/documentation/api-design-guidelines/#clarity-over-brevity)

短いコードを追い求め過ぎて、可読性など損なうのは良くない。

## [ドキュメンテーションコメントを書きましょう](https://swift.org/documentation/api-design-guidelines/#write-doc-comment)

すべての定義にはドキュメンテーションコメントを書きましょう。
(訳注: 処理に添えるコメントではなくクラス・メソッド・フィールド定義などのコメントを指している)

- [MarkdownのSwift方言](https://developer.apple.com/library/prerelease/mac/documentation/Xcode/Reference/xcode_markup_formatting_ref/)を活用しましょう
- まずはサマリーを書きましょう
    - サマリーが最重要です
    - ピリオド終わりの簡潔な一文で説明しましょう
    - メソッドの**すること**と**結果(戻り値)**を述べましょう
    - `subscript`が何にアクセスしているか述べましょう
    - イニシャライザーが生成するものを述べましょう
    - 宣言されたエンティティが**何であるか**を述べましょう
- もし必要であれば、サマリーに続いて1つ空行を挟んで、詳細を書きましょう
  - 段落や箇条書きを活用しましょう(訳注: Gitのコミットメッセージの作法と似てますね)
  - [Symbol Documentation Markup Syntax](https://developer.apple.com/library/prerelease/mac/documentation/Xcode/Reference/xcode_markup_formatting_ref/SymbolDocumentation.html#//apple_ref/doc/uid/TP40016497-CH51-SW1)を活用しましょう
  - [symbol command syntax](https://developer.apple.com/library/prerelease/mac/documentation/Xcode/Reference/xcode_markup_formatting_ref/SymbolDocumentation.html#//apple_ref/doc/uid/TP40016497-CH51-SW13)を学習・活用しましょう
    - `Attention`, `Author`, `Bug`など特定のワードで始まるものは特別な表示がされます(原文に全リスト掲載)  

(原文にコード例が豊富に載っているのそれ見た方が分かりやすいかと :eyes:)

# [命名](https://swift.org/documentation/api-design-guidelines/#naming)

クラス・メソッド・変数などの命名について。

## [使い方が明確になるように配慮しましょう](https://swift.org/documentation/api-design-guidelines/#promote-clear-usage)

- 曖昧さを排除するために充分な説明を含みましょう
- 逆に、冗長なワードは省きましょう
- 変数・引数・関連型(`Associated Type`)の**型ではなく役割**に応じた名前付けをしましょう
- 型の弱い定義はそれを補う説明を添えましょう
  - `NSObject`・`Any`・`AnyObject`などが引数の時は何を渡すべきか曖昧なのでヒントを含む名前にしましょう

## [流暢な表現を心がけましょう](https://swift.org/documentation/api-design-guidelines/#be-grammatical)

- 英文として流れるように読めるようなメソッド名にしましょう(引数のラベルも含めて)
- ファクトリーメソッドは、`make`で始まる名前にしましょう
    - 例: `x.makeIterator()`
- イニシャライザー・ファクトリーメソッドは、先頭引数の説明を省きましょう
    - 例: `factory.makeWidget(havingGearCount: 42)`ではなく`factory.makeWidget(gears: 42)`が良い
- 関数・メソッドの命名は、その副作用に応じましょう
    - 変更操作しないメソッドは、名詞にしましょう
        - `x.distanceTo(x)`, `i.successor()`
    - 変更操作するメソッドは、命令形の動詞にしましょう 
        - `x.reverse()`, `x.sort()`, `x.append(y)`
    - 動詞での表現が自然であり、かつ変更操作するメソッドと同等の、変更操作しないメソッドがある場合、`ed/ding`を添えましょう
        - `x.sort()/x.sorted()`, `x.append(y)/x.appending(y)`(訳注: 変更操作しないメソッドは戻り値で新しいオブジェクトとして返す処理となる)
            - 動詞に直接目的語があって`ed`が不自然な時、`ing`を付ける(訳注: [Swiftで学ぶ英文法: 現在分詞と過去分詞 - Qiita](http://qiita.com/gonsee/items/4e245f5e118b66e22d99))
        - `x.isEmpty`, `line1.intersects(line2)`
    - 名詞での表現が自然であり、かつ変更操作するメソッドと同等の、変更操作しないメソッドがある場合、変更無し: 名詞、変更あり: `form` + 名詞、としましょう
        - 変更無し: `x = y.union(z)`、変更あり: `y.formUnion(z)` 
- 変更操作しない、戻り値がBoolのメソッド・プロパティは、レシーバーの検証となるような名前にしましょう
    - `x.isEmpty`, `line1.intersects(line2)`
- それが何であるかを示すプロトコルは名詞にしましょう
  - `Collection`
- 何を出来るかを示すプロトコルは`able/ible/ing`で終わるような名前にしましょう
  - `Equatable`, `ProgressReporting`
- その他の型・プロパティ・変数・定数の名前は名詞にしましょう

## [専門用語を良い感じに活用しましょう](https://swift.org/documentation/api-design-guidelines/#use-terminology-well)

- よく知られていない分かりにくい言葉は避けましょう
  - 例えば`skin`が適しているのに`epidermis`など使うのはダメ
- 確立された用例に従いましょう
  - 専門用語を使うのは一般的な用語より意味が明確になるときに限るようにしましょう
- 省略形は避けましょう(特に辞書に載っていないような一般的で無いものは)
- 慣習に従いましょう
  - 隣接したデータ構造は、`List`より`Array`が適している
  - `sin(x)`は`sine(x)`と名付けるべきではない

# [慣例](https://swift.org/documentation/api-design-guidelines/#conventions)

## [一般的な慣例](https://swift.org/documentation/api-design-guidelines/#general-conventions)

- O(1)ではない`computed property`には、オーダー・計算量などの説明を添えましょう
  - プロパティは通常O(1)であることが一般的なので
- 以下のケースを除いて、基本的に関数よりもメソッド・プロパティが望ましい
  - 明確な`self`が無いもの(訳自信無し)
    - `min(x, y, z)`
  - 特に何にも属さないような一般的なもの
    - `print(x)`
  - 関数として一般的なもの
    - `sin(x)`
- 大文字小文字ルールを守る
  - 型・Protocol: `UpperCamelCase`
  - それ以外: `lowerCamelCase`
- 用途など同じメソッド群は同名で引数定義など変えるだけで良い(オーバーロード)
  - 逆に用途・意味が違うものは違う名前とする
  - 戻り値の型だけが異なるオーバーロードは避ける

## [引数](https://swift.org/documentation/api-design-guidelines/#parameters)

- 引数自身がドキュメントの役割を果たすように命名する
    - ドキュメントで引数名を指す時にも分かりやすい名前を意識する
- デフォルト引数を活用する
  - メインの用途を満たすように、オプション的な引数には適切なデフォルト引数を与えておくと、利用時に楽
- 後ろの引数に行くにつれて、デフォルトぽいものになるように、引数順を並べる

## [引数のラベル](https://swift.org/documentation/api-design-guidelines/#argument-labels)

- 引数区別に意味が薄いときはラベルを省略する
    - `min(number1, number2)`
- キャストぽいイニシャライザーではラベルを省略する
    - `Int64(someUInt32)`
- 第一引数が前置詞的な役割を担う場合は、ラベルを与える
    - `x.removeBoxes(havingLength: 12)`
    - 複数の引数が前置詞的な意味を持つときは、例外としてメソッド名に説明を移動
        - `a.move(toX: b, y: c)`ではなく`a.moveTo(x: b, y: c)`
- 一方、第一引数が文法的なフレーズを担うときは、ラベルを省略して、メソッド名に説明を付ける
    - `x.addSubview(y)`
    - 逆にそうでは無いときはラベルを付ける(`view.dismiss(animated: false)`)
- その他の全ての引数に適切なラベルを付ける

# [特別なケースの指針](https://swift.org/documentation/api-design-guidelines/#special-instructions)

- クロージャーの引数・タプルのメンバーにはラベルを付ける
- `Any`・`AnyObject`・制約無しのジェネリクスの場合、特に気を付ける
  - 原文のコード見てください（´・ω・｀）


---

今日(2016/01/31)、Hacker Newsやはてぶであがっていたので、新しいドキュメントかと勘違いしましたが、以前からあって微妙に更新されただけの模様です（´・ω・｀）

<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr"><a href="https://twitter.com/_mono">@_mono</a> 若干古いですがご参考にどうぞ :-) <a href="https://t.co/C5W83crXcm">https://t.co/C5W83crXcm</a></p>&mdash; Goichi Hirakawa (@gooichi) <a href="https://twitter.com/gooichi/status/693653139463929856">January 31, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>