LoginSignup
4
1

More than 5 years have passed since last update.

StringやDataに意味を持たせる手段として列挙型を使う

Last updated at Posted at 2018-05-04

Swiftの列挙型(=enum)のassociated valuesの仕組みを使ってコードの保守性を向上させよう、という記事です。
※この記事が前提にしている開発環境はXcode9.3 / Swift4.1です。

String型やData型を列挙型のassociated valuesにして意味を与える

文字列やバイナリデータって、変数名に気をつけないと可読性・保守性が凄く落ちますよね。
例えば以下のような「暗号化された画像をWEBからロードしてきて表示する」コードの場合↓

func load() -> Data? {
  let imageUrl = URL(string: "https://www.example.com/some/secret/image")!
  let data = try? Data(contentsOf: imageUrl) // dataは暗号化されている
  return data
}

if let data = load() {
  imageView.image = UIImage(data: data) // ❌dataはまだ複合されていないので表示できない
}

この例ではdataが復号化されないままUIImageのイニシャライザに渡されているので画像が表示されなくなります。
この例はとても単純な実装なのでこういったミスをすることは想像しにくいかもしれませんが、暗号化されたデータが複数のfunctionを跨る設計になっていると、こういった不具合が起きやすくなると思います。
※余談ですが、先日Twitterさんが誤ってハッシュ化する前のパスワードをログに書き込んでしまっていた件はそういった実装が原因で「ハッシュ化前のパスワード」と「ハッシュ化後のパスワード」が区別できないような実装になっていて起きたのではないか?と想像しています。

この問題をSwiftの列挙型を使って解消する一例を挙げると、以下のようになります。

enum ImageData {
  case encrypted(Data)
  case decrypted(Data)
}

func load() -> ImageData? {
  let imageUrl = URL(string: "https://www.example.com/some/secret/image")!
  if let data = try? Data(contentsOf: imageUrl) {// dataは暗号化されている
    return .encrypted(data) // 暗号化されているDataだということを明示した値を返却する
  }
  return nil
}

if let imageData = load(), case .decrypted(let data) = imageData {
  imageView.image = UIImage(data: data) // ⭕️imageDataが複合されているときだけこの行が実行される
}

この実装でもDataの復号化処理は書いていないので結局画像は表示されないのですが、ImageData.decryptedであること(=復号化済みであること)を判定するif文が書けるおかげでUIImageに暗号化されたままのDataを渡すことがなくなり、不意の事故を防いで適切なエラーハンドリングを実装する事ができるようになりました。

このような形で、Data型やString型の値をenumでラップしてあげることでそれらの値に意味を持たせる事ができます。
今回は暗号化済データ/復号化済データの区別に用いましたが、実行ステップを経ていく中でデータの形が変わる類の値であれば、何にでも活用できるTipsだと思います。

チーム開発では分かりやすい変数名をつけたりすることも大切ですが、こういうアプローチで保守性を上げることもできますよ、というご紹介でした。
どなたかのお役に立てば幸いです。

4
1
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
4
1