swift3.0 公式設計ガイドライン 和訳


swiftの設計ガイドラインを参考にまとめます。
`https://swift.org/documentation/api-design-guidelines/`

swift2.xからswift3.0に、大きく破壊的な変更が設けられたことは今でも記憶に新しいです。
swift3.0以降の設計はAPI Design Guidelinesに起因するので、
今からswiftを初める人も、Objective-CからiOSに触れている人も、よりswiftらしい記述を求められているため、まとめました。


##原則
- 英文として違和感のない記述をする
- 簡潔さより明快さを大切にする


##命名規則
###明快な使用を促進
- 曖昧さを避けるために必要な単語を全て含めること

```
employees.remove(at: x) //Good
employees.remove(x) //Bad ⇒ unclear: are we removing x?
```

- 必要のない単語は省略すること

```
allViews.remove(cancelButton) //Good
allViews.removeElement(cancelButton) //Bad
```

- 型の制約ではなく、役割に応じた命名をすること

```
//Bad
var string = "Hello"
protocol ViewController {
  associatedtype ViewType : View
}
class ProductionLine {
  func restock(from widgetFactory: WidgetFactory)
}

//Good
var greeting = "Hello"
protocol ViewController {
  associatedtype ContentView : View
}
class ProductionLine {
  func restock(from supplier: WidgetFactory)
}
```

- 引数の役割を明確にするために情報を補うこと

```
grid.addObserver(self, forKeyPath: graphics) //Good
grid.add(self, for: graphics) //Bad
```

###流暢な使い方に努める
- メソッドや関数を英文法的に成り立たせる

```
x.insert(y, at: z) //Good
x.subViews(havingColor: y) //Good
x.capitalizingNouns() //Good
x.insert(y, position: z) //Bad
x.subViews(color: y) //Bad
x.nounCapitalize() //Bad
```

- オブジェクトを作成するメソッドは `make` をつける

```
x.makeIterator()
```

- 暗示されるフレーズには、第一引数に含めない

```
let foreground = Color(red: 32, green: 64, blue: 128) //Good
let foreground = Color(havingRGBValuesRed: 32, green: 64, andBlue: 128) //Bad
```

- 副作用に応じたメソッドを命名する
    -  メソッドの動作を動詞で表現する場合 `ed` や `ing` を付与する
    -  メソッドの動作を名詞で表現する場合 `form` を付与する

```
x.sort()  => z = x.sorted()
x.append(y) => z = x.appending(y) 

x = y.union(z) => y.formUnion(z)
```

- 真偽判定するメソッドを分かるように命名する

```
array.isEmpty
view.isHidden
```

- プロトコルが何であるかを表す場合は名詞にする

```
Collection, Iterator など
```

- プロトコルの能力を表す場合は末尾を `able` , `ible` , `ing` にする

```
Equatable, ProgressReporting など
```
   
- その他の型/引数/変数/定数は基本的に名詞にする

###専門語は上手に用いる
- 曖昧な言い回しを避ける
- 確立された意味に固執する
- 略語は避ける
- 先例を受け入れる


##慣習
###一般
- computed プロパティの複雑化に注意する
- グローバル関数よりメソッドやプロパティを使う

```
min(x,y,z) //明確な selfが存在しない場合
print(x) //慣習が汎用的な場合
sin(x) //関数の構文が確立されたドメインの表記の場合
```

- キャメルケースに従う

```
UpperCamelCase //型やプロトコル名
lowerCamelCase //それ以外
```

- メソッドで基底の名前を共有する

```
extension Shape {
  
  func contains(_ other: Point) -> Bool { ... }
  func contains(_ other: Shape) -> Bool { ... }
  func contains(_ other: LineSegment) -> Bool { ... }
}

extension Collection where Element : Equatable {

  func contains(_ sought: Element) -> Bool { ... }
}
```

###パラメータ
- 引数名に説明の役割を持たせる

```
mutating func replaceRange(_ subRange: Range, with newElements: [E]) //Good
mutating func replaceRange(_ r: Range, with: [E]) //Bad
```

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

```
第二引数以降の関連しない情報を隠す
let order = lastName.compare(royalFamilyName) //Good
let order = lastName.compare(royalFamilyName, options: [], range: nil, locale: nil) // Bad
```

- デフォルト引数は最後に配置する
    - デフォルト値を持たない引数は、メソッドにおいて重要な意味を持つためです。


###引数ラベル

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

- 引数が区別出来ない場合は、ラベルを省略する

```
min(number1, number2)
zip(sequence1, sequence2)
```

- 初期宣言の第一引数ラベルは省略する
- メソッド名に引数ラベルを付ける
    - 第一引数が英文の一部を構成する時に、他の引数を考慮してバランスが悪くなる場合の対応
    - しかしラベルを省略することで逆に、曖昧になる場合にはラベルを付与する

```
a.moveTo(x: b, y: c) //Good
a.fadeFrom(red: b, green: c, blue: d) // Good
a.move(toX: b, y: c) //Bad
a.fade(fromRed: b, green: c, blue: d) //Bad
      
view.dismiss(animated: false) //Good
let text = words.split(maxSplits: 12) //Good
view.dismiss(false)   //Bad ⇒ Don't dismiss? Dismiss a Bool?
words.split(12)       //Bad ⇒ Split the number 12?
```

- それ以外に対しては全てにラベルをつける