31
Swift API Design Guidelines (Dec 3, 2015) Takaaki Tanaka, Goichi Hirakawa

Swift API Design Guidelines (dec 3, 2015)

Embed Size (px)

Citation preview

Page 1: Swift API Design Guidelines (dec 3, 2015)

Swift API Design Guidelines (Dec 3, 2015)

Takaaki Tanaka, Goichi Hirakawa

Page 2: Swift API Design Guidelines (dec 3, 2015)

About Me

• 田中 孝明 (Takaaki Tanaka)

• @kongmingtrap

• iOS Developer (Swift / Objective-C)

• GyazSquare / GitHub

Page 3: Swift API Design Guidelines (dec 3, 2015)

About Me• 平川 剛一 (Goichi Hirakawa)

• @gooichi

• OS X / iOSソフトウェアエンジニア(フリー)

• GyazSquare / GitHub

• Mailer、デバイス制御、MDM系など

• Objective-C歴XX年、最近はSwiftにはまる…

Page 4: Swift API Design Guidelines (dec 3, 2015)

Swift is Open Source• 2015/12/03にオープンソースとして公開

• 2.2リリース:2016年春頃

• 3.0リリース:2016年秋頃

• 3.0の目標の一つ:

API design guidelines: 定義と適用

Page 5: Swift API Design Guidelines (dec 3, 2015)

Agenda• 2015-12-03版APIガイドラインの紹介

• Fundamentals: 基礎

• Naming: 命名

• Conventions: 規約

• Special instructions: 特記事項

Page 6: Swift API Design Guidelines (dec 3, 2015)

Agenda• 2015-12-03版APIガイドラインの紹介

• Fundamentals: 基礎

• Naming: 命名

• Conventions: 規約

• Special instructions: 特記事項

Page 7: Swift API Design Guidelines (dec 3, 2015)

Fundamentals• 利用時の明確さ

• もっとも重要な目標

• 明確さは簡潔さより重要

• 最小の文字数が目標ではない

• ドキュメントコメントを書く

Page 8: Swift API Design Guidelines (dec 3, 2015)

Write a Document Comment

• すべてのメソッドとプロパティ

• MarkDownのSwift方言を使う /// Returns the first index where `element` appears in `self`, /// or `nil` if `element` is not found. /// /// - Complexity: O(`self.count`). public func indexOf(element: Generator.Element) -> Index? {

Page 9: Swift API Design Guidelines (dec 3, 2015)

Agenda• 2015-12-03版APIガイドラインの紹介

• Fundamentals: 基礎

• Naming: 命名

• Conventions: 規約

• Special instructions: 特記事項

Page 10: Swift API Design Guidelines (dec 3, 2015)

Naming

• Promote Clear Usage: 明快な語法を推進

• Be Grammatical: 文法に正しく

• Use Terminology Well: 専門用語をうまく使用

Page 11: Swift API Design Guidelines (dec 3, 2015)

Promote Clear Usage• 曖昧さを避けること例えば、以下のようなポジションを指定して削除するメソッドがあった場合、 public mutating func removeAt(position: Index) -> Element

employees.removeAt(x)

Atを省略すると位置を指定するのか、employeesの 要素を指定するのか曖昧になる: employees.remove(x) // unclear: are we removing x?

Page 12: Swift API Design Guidelines (dec 3, 2015)

Promote Clear Usage• 不要な単語は省略する 余剰な情報は省略すべき。Elementを管理するオブジェクトのElementを削除するメソッドに対して、メソッド名にElementを含めるのは余剰な情報である:

public mutating func removeElement(member: Element) -> Element?

allViews.removeElement(cancelButton)

以下のようにするのがよい: public mutating func remove(member: Element) -> Element?

allViews.remove(cancelButton) // clearer

Page 13: Swift API Design Guidelines (dec 3, 2015)

Promote Clear Usage• パラメータには役割を明確にするための補足情報を追加するNSObject、Any、AnyObjectや基本的な型(IntやString)のパラメータは役割を明確にした名前をつける:

func add(observer: NSObject, for keyPath: String)

grid.add(self, for: graphics) // vague

以下のように、selfはObserver、StringはkeyPathとして使用することを明示する: func addObserver(_ observer: NSObject, forKeyPath path: String)

grid.addObserver(self, forKeyPath: graphics) // clear

Page 14: Swift API Design Guidelines (dec 3, 2015)

Be Grammatical

• mutatingメソッドには動詞句を使用する

• non-mutatingメソッドには名詞句を使用する

• mutatingメソッドが動詞句の場合、対応する non-mutatingメソッドには「ed/ing」をつける

Page 15: Swift API Design Guidelines (dec 3, 2015)

Be Grammatical• non-mutatingなBooleanメソッド、プロパティは以下のようにする x.isEmpty, line1.intersects(line2)

• Protocolは特徴を名詞で記述し、接尾語に「able」、「ible」、「ing」をつける

• その他の変数、プロパティ、定数は名詞で記述する

Page 16: Swift API Design Guidelines (dec 3, 2015)

Use Terminology Well

• あまり知られてない専門用語は避ける

• 専門用語を使用する場合は確立された意味に従う

• 専門家を驚かせない

• 初心者を惑わせない

Page 17: Swift API Design Guidelines (dec 3, 2015)

Use Terminology Well

• 略語は避ける

• 先例を受け入れる連続したデータ構造ではListよりもArrayと名前につける(Arrayはモダン・コンピューティングの基礎であり、すべてのプログラマが知っている)

Page 18: Swift API Design Guidelines (dec 3, 2015)

Agenda• 2015-12-03版APIガイドラインの紹介

• Fundamentals: 基礎

• Naming: 命名

• Conventions: 規約

• Special instructions: 特記事項

Page 19: Swift API Design Guidelines (dec 3, 2015)

Conventions

• General Conventions: 一般的な規約

• Parameters: パラメータ

Page 20: Swift API Design Guidelines (dec 3, 2015)

General Conventions• O(1)ではない計算型プロパティの複雑さは文章化

• フリー関数よりメソッドやプロパティを選択する

• ケース(大文字・小文字)の規約に従う

• 同じ基本的な意味を共有するとき、メソッドはベース名を共有できる

Page 21: Swift API Design Guidelines (dec 3, 2015)

Free Functions• フリー関数は特別な場合のみ使用される:

1.明白な“self”がないとき min(x, y, z)

2.関数が制約なく汎用的なとき print(x)

3.関数の構文が確立されたドメイン表記の一部のとき sin(x)

Page 22: Swift API Design Guidelines (dec 3, 2015)

Parameters• デフォルト引数を利用する

• メソッドファミリーの利用より一般的に好ましい

• デフォルトを持つパラメータは最後の方に置く

• 引数ラベルの存在は言語のデフォルト設定に従う

例外:

1.拡張型変換と見られるべきであるイニシャライザ

2.すべてのパラメータが有効に区別できないピアのとき

3.最初の引数がデフォルト設定されたとき

Page 23: Swift API Design Guidelines (dec 3, 2015)

Argument Labels• メソッドや関数の最初の引数は必須の引数ラベルを持つべきではない

• メソッドや関数の他のパラメータは必須の引数ラベルを持つべきである

• イニシャライザのすべてのパラメータは必須の引数ラベルを持つべきである

Page 24: Swift API Design Guidelines (dec 3, 2015)

Exception 1• 拡張型変換(widening type conversions):元が取り得るすべての値を許容可能な型への変換

• 縮小型変換(narrowing type conversions): 値の一部を保持できない型への変換 extension UInt32 { init(_ value: Int16) // widening, so no label init(truncating bits: UInt64) // narrowing init(saturating value: UInt64) // narrowing }

Page 25: Swift API Design Guidelines (dec 3, 2015)

Exception 2

• すべてのパラメータが有効に区別できないピアの ときのよく知られた例: min(number1, number2)

zip(sequence1, sequence2)

Page 26: Swift API Design Guidelines (dec 3, 2015)

Exception 3• 最初の引数がデフォルト設定されたときの例

extension Document { func close(completionHandler completion: ((Bool) -> Void)? = nil) } doc1.close() doc2.close(completionHandler: app.quit)

extension Document { func close(completion: ((Bool) -> Void)? = nil) } doc.close(app.quit) // Closing the quit function?

extension Document { func closeWithCompletionHandler(completion: ((Bool) -> Void)? = nil) } doc.closeWithCompletionHandler() // What completion handler?

Page 27: Swift API Design Guidelines (dec 3, 2015)

Agenda• 2015-12-03版APIガイドラインの紹介

• Fundamentals: 基礎

• Naming: 命名

• Conventions: 規約

• Special instructions: 特記事項

Page 28: Swift API Design Guidelines (dec 3, 2015)

Special Instructions• 制約のない多態性に細心の注意を払うこと

• Any、AnyObjectと制約のないジェネリックパラメータ

• ドキュメントコメントツールフレンドリーにする

• リッチなフォーマットのドキュメントが自動生成

• Xcodeで表示される

• 優れた要約を記述することがより重要である

Page 29: Swift API Design Guidelines (dec 3, 2015)

Unconstrained Polymorphism• 例えば、以下のオーバーロードのセットを考える:

struct Array { /// Inserts `newElement` at `self.endIndex`. public mutating func append(newElement: Element)

/// Inserts the contents of `newElements`, in order, at /// `self.endIndex`. public mutating func append< S : SequenceType where S.Generator.Element == Element >(newElements: S) }

ElementがAnyのとき、曖昧になる(単一のElementがElementのシーケンスと同じ型扱い) var values: [Any] = [1, "a"] values.append([2, 3, 4]) // [1, "a", [2, 3, 4]] or [1, "a", 2, 3, 4]?

Page 30: Swift API Design Guidelines (dec 3, 2015)

Unconstrained Polymorphism

• 曖昧さを排除するために2番目のオーバーロードをより明確に命名する: struct Array { /// Inserts `newElement` at `self.endIndex`. public mutating func append(newElement: Element)

/// Inserts the contents of `newElements`, in order, at /// `self.endIndex`. public mutating func appendContentsOf< S : SequenceType where S.Generator.Element == Element >(newElements: S) }

Page 31: Swift API Design Guidelines (dec 3, 2015)

Conclusion• Swift 3 API Guidelines Review

• GitHubで公開

• Swift 3 API Guidelinesの成果の一部

• Swift 3インポータ自動適用結果が見れる

➡ Swift 2.xでもある程度意識しながらコードを書いた方がよい

• ただし、ガイドラインはあくまでガイドライン(指針)

• 細かな部分はプロジェクトやグループで決めが必要

• ガイドライン自体がGitHub上に欲しい