10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事は 過去の自分に教えたい、ソフトウェア品質の心得 のアドベントカレンダーの記事です。

もっと早く知りたかった、イミュータブルな実装方法

「過去の自分に教えたい」品質を高める方法として、テストしやすい実装が重要ということが頭に浮かびました。
イミュータブルな実装にすると、副作用が発生しません。

この副作用のない構造をシステム内部で広く活用ができれば、内部品質を飛躍的に高まる思考に自然と行き着いていくと感じています。

そのため、この発想を知った時には楽しかったですが、この効果を実感したときに、もっと早く知っていればなーと感じました。
今回はそのイミュータブルな実装を知ることで与える内部品質全体について書きました。

イミュータブルな実装とは?

ミュータブルな実装とイミュータブルな実装の違い

ミュータブルな実装とは、値の変更が起きるオブジェクト
例えば、連想配列型のオブジェクトを引数で渡して、変更があった情報を更新されるような処理の場合、この連想配列はどのタイミングで参照したかによって内容が変わります。

イミュータブルな実装とは、値の変更が起きないオブジェクト
オブジェクトを生成した瞬間そのオブジェクトは完成しており変更はできません。もし変更を加えたい場合には新しい値のオブジェクトを作る必要があります。変更の参考にしたい元のオブジェクトと変更したい値を使って新しいオブジェクトをつくることになります。
そうすると、1度作られたオブジェクトは変更されることがありません。

副作用のないメソッド

イミュータブルな実装でロジックを組み合わせれば、副作用のない実装を作ることができます。

副作用ない実装とは、何度実行しても同じ値を与えれば全く同じ結果が返ってくるロジックのことです。
副作用のある実装とは、例えば裏でデータベースが違う値を持っていたり、処理の途中で非同期処理の値を受け付けたりすると、メソッドに与えた引数は同じであっても違う値が返ってくることになります。その処理は副作用がある処理になります。

副作用のないメソッドはそのロジックが全く同じように実行されるため、同じ値を渡せば必ず同じ値が返ってきます。
image.png

ウェブアプリケーションで副作用のないロジックを実現する

通常のウェブアプリケーションではリクエスト1件に対して1件のレスポンスを返します。
つまりリクエストを処理するロジックを副作用のない処理にすることが出来れば、同じ値を渡せば、必ず同じ値が返ってくるようになります。
image.png

しかし、副作用が発生しやすい処理として、データを保存したり取り出したりする取り扱う処理があります。
リクエストの処理を元に取り出したり、保存したりしますが、これらはデータを保存している状態によって、ロジックが何を返すかが変わります。このデータの状態はミュータブルであり、見通しが悪くなりやすいです。

ウェブアプリケーションでのデータが保存される箇所は概ね3つだと考えています。

  • データベース
  • セッションデータ (Cookie)
  • 外部連携データ

image.png

これらの処理をなるべくロジックのコアに入らないように工夫することで、テストしやすく、見通しが良いコードになりやすくなると感じます。重要なロジックのみをテストしやすく、データの接続テストと分離することができます。

自然と実現されるクリーンアーキテクチャの依存階層

この構造を綺麗に実現しようとしたときに、自然とクリーンアーキテクチャのユースケースの形になります。
副作用のないロジックで閉じ込められるように実装すると、テストしやすい実装はユースケースに閉じ込められ、変更の影響が大きな処理は階層の外側に押し出す形をとります。

image.png

依存性の逆転が必要な箇所はDIを利用することで、コアなロジックをテストする時はDIを使ってモックを差し込みやすくなり、再現性の高いテストが高速で実行できるようにもなります。

自然な流れで実装すると自然と左の依存の流れになります。
副作用を抑えながら実装をすると、右のような依存になります。
UIは入力のリクエストデータに加え、セッションデータも含まれます。
インフラストラクチャーは主にデータベースになります。

image.png

すると自然とクリーンアーキテクチャの依存関係にたどり着きます。
この構造であれば、業務処理のテストは外部のリクエストの形式やDBの状態に依存することなくテストが可能になるため、堅牢で柔軟な内部構造を保ちやすくなります。

まとめ

イミュータブルな実装をして副作用を減らせば、内部品質が飛躍的に高まる切っ掛けになったと感じていて、昔の自分が早くしれたら良かったなー!と思った次第です。

設計から入るのではなく、実装で表現したいことから理解することが自分の感覚には合っていました。
設計よりも実装が楽しいと思っていた時代で、実装のために設計が重要だと実感したタイミングでも合ったと思います。

もし良ければ、イミュータブルで副作用のない実装を意識してコードを書いてみてください。

一緒に働くエンジニアやエンジニアリングマネージャを探しております

今日のこの話をもっと話したい人、私の会社の仕事について話したい人はカジュアルに話しましょう!
Qiitaの記事を読んだと書いて登録をお願いします

会社HP

今度、こちらのオンラインイベントに登壇します!
オンライなのでお気軽に登録してください。

10
4
1

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?