iOSDC 2019 トークノート:Swiftクリーンコードアドベンチャー 〜日々の苦悩を乗り越え、確かな選択をするために〜

iOSDC Japan

はじめに

こんにちは。今年フェンリルにiOSエンジニアとして入社した西村滉祐と申します。

今回、僕は9月5日から3日間行われたiOSDC 2019に参加し、そこで色々なトークを見ました。その中から得る事ができた知識や知見などを共有したいと思います。

今回はタイトルにある通り、二日目に行われたshizさんによる「Swiftクリーンコードアドベンチャー 〜日々の苦悩を乗り越え、確かな選択をするために〜」から、クリーンコードとジェネリクスについて話します。

スライドはこちら:

https://speakerdeck.com/shiz/swift-clean-code

クリーンコードとは

クリーンコードは「Clean Architecture: A Craftsman's Guide to Software Structure and Design」や「Clean Code: A Handbook of Agile Software Craftsmanship」などの著者として知られるRobert C. Martinが提唱したものだそうです。彼はUncle Bobとしても知られているらしいので、この記事でもUncle Bobと呼ぶ事にします。

さてUncle Bob曰く、クリーンコードとは読みやすいコードを指しています。しかし人によってその意味するところは違い、クリーンコードは長年の経験と試行錯誤の積み重ねからの学びであると主張しています。

とはいえ、俯瞰してみると以下の3つの共通点が見られます:

  1. わかりやすい
    • 読みやすさ、理解のしやすさ etc
  2. 安全である
    • バグが発生しづらい、テストが容易 etc
  3. 変更に強い
    • 修正時の影響範囲が限定的、機能追加時の既存コードへの影響度が小さい etc

ジェネリックについて

クリーンコードを書くためのアプローチとしてジェネリックが挙げられるでしょう。ジェネリックとは、「具体的なデータ型に直接依存せず、汎用的に利用可能な状態」であると定義しています。

例えば2つの値を入れ替えるswapTwoValuesという関数を、ジェネリック関数としてSwiftで書くなら

func swapTwoValues<T>(_ a: inout T, _ b: inout T)

というようになり、Tはひとつめの引数aに渡した型で決定されるプレイスホルダー的な役割を持ちます(bの型はaに渡されたものと同じになります)。このswapTwoValuesという関数を、ジェネリクスを使わないで色々な型について実装しようとするなら、それぞれの型で全く同じコードを書く事になりますが、ジェネリクスを使う事でそれを解消できる訳です。

ジェネリックコードとクリーンコード

ジェネリックコードの特徴は汎用的で再利用可能なコードという事です。上述したswapTwoValuesメソッドのように、似た構造を持つコードをうまく一般化してジェネリックコードにする事で、コードの量が減り、冗長な繰り返しが消えます。このようにジェネリックコードは可読性の観点からコードをクリーンにします。

プロトコル

さて、Swiftにおいてジェネリックプログラミングを実現する際に重要なもののひとつがプロトコルです。Appleは2015年のWWDCでプロトコル指向プログラミングのトークを行いました。プロトコル指向プログラミングとはひとつのプログラミングパラダイムであり、プロトコルを用いてプログラムの設計を考えます。しかし、果たしてこれは「すべてプロトコルから始めよ」という事を意味するのでしょうか?

スライドにある文章を引用すると、

if you want to write a generalized sort or binary search… Don't start with a class. Start With a protocol

とあります。つまり、何か一般化する必要がある時にプロトコルから始めよという事です。さらにスライドからの文章を引用すると、

To start with some concrete types, and then try and unify them with a protocol

とあります。クリーンコードを書こうとして一般化する前に、まず具体的な型で始め、その後で一般化した方が良いと判断したらプロトコルで一般化すべき具体的な型を統一するとよいでしょう。重複の消去や汎用化の必要がない限り、無理してジェネリックにしない方がいいです。

終わりに:クリーンコードを書き続けるには

クリーンコードとして挙げられる特徴として、

  1. わかりやすい
  2. 安全である
  3. 変更に強い

というものがあり、今回はそのアプローチのひとつとしてジェネリックコードを紹介しました。似た構造を持つコードをうまく一般化した上でのジェネリックコードはコードの可読性に貢献するでしょう。

最後にボーイスカウトの規則というものを紹介します。これは簡単にいうと「元の状態よりも良くしていきなさい」というものです。これがUncle Bobによってエンジニアの世界に輸入され、次のように主張されています:

Always leave the code you're editing a little better than you found it

(引用元:https://medium.com/@biratkirat/step-8-the-boy-scout-rule-robert-c-martin-uncle-bob-9ac839778385)

クリーンコードを書き続けるには、それぞれがコードの改善を継続的に行っていくというプロ意識が必要です。その過程で経験や試行錯誤を積み重ねていく事で、一貫した価値体系が構築されていくのかもしれません。