LoginSignup
16
12

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-05-22

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
  • 副作用に応じたメソッドを命名する
    • メソッドの動作を動詞で表現する場合 eding を付与する
    • メソッドの動作を名詞で表現する場合 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?
  • それ以外に対しては全てにラベルをつける
16
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
12