はじめに
最近クリーンアーキテクチャやDDDについての話を聞いたり、記事を目にすることが多いです。
そこで実装例で度々出てくる言語としてScalaがあります。
筆者自身もScalaでクリーンアーキテクチャ&DDDを実践しており、普段からその相性の良さを実感しています。
ではなぜScalaとクリーンアーキテクチャは相性がいいのでしょう?
今回はScalaが持つ関数型言語という側面と、クリーンアーキテクチャの相性の良さを考察します。
クリーンアーキテクチャの勘所
クリーンアーキテクチャとはClean Architecture 達人に学ぶソフトウェアの構造と設計で提唱されているソフトウェアアーキテクチャです。
その構造はよく見る円がいくつか重なった図で説明されます。
初見では何を表しているかさっぱりだと思いますが、伝えたいことは単純です。
それはソフトウェアの詳細を方針に一方方向に依存させるということです。
では詳細と方針とはなんのことで、なぜ一方方向の依存が推奨されるのでしょうか?
ソフトに取り替え可能な詳細
ここで言う詳細とはIOデバイスやプロトコルなどのサービス、つまり具体的に使用されるテックスタックのことです。
これらは非常に変化しやすく、逆にそうでなければなりません。
なぜなら詳細はプロダクトの具体的な要件を決めるものです。
例えば通信方式、保存方式などが当たります。
これらの要件は一度決定されたきり変更がないとは言えません。
新しい通信プロトコルの登場、革新的な保存方式。
詳細は常に変化の波にさらされています。
したがって変更は予期しうるものであり、そこに向けて対処するのがソフトウェアアーキテクトの責務です。
詳細がいかにソフトに取り替え可能かということがソフトウェアをソフトウェアたらしめているのです。
プロダクトそのものである方針
プロダクトとは課題を解決するものです。
語弊を恐れずに言えば面倒なことを自動化することに他なりません。
すなわち何らかの面倒さという課題を解決してくれるものなのです。
その面倒さは領域によって様々ですが、領域によって固定されてもいます。
プロダクトを意味づけるのはこの面倒さを解決するための方針なのです。
方針 is 唯我独尊
方針は何者にも影響されるべきではありません。
なぜなら上で述べたとおりそれこそがプロダクトそのものだからです。
技術革新や新しいデバイスの登場によってプロダクトが解決したい課題が影響されるべきではありません。
DBやプロトコルの変更によって、解決したかった面倒だったことが面倒ではなくなるなどということは起きてはなりませんし、起こり得ないことなのです。
方針が実現したいものに詳細がただ従うだけなのです。
これをクリーンアーキテクチャでは中心に方針を、周辺に詳細を配置した図で表し、外から内への依存と表現しているのです。
関数型プログラミングと副作用
純粋関数志向
ここで言う関数型とは副作用を廃した純粋関数型志向のプログラミングスタイルのことを指します。
すなわち同じ入力値に対して毎回同じ値を返し、更に副作用を起こさない関数のことです。
例えるなら数学の関数のようなものだと思ってください。
関数型スタイルで書くとプログラムの大部分は副作用のない単なる数学の関数の合成のように記述できます。
副作用を閉じ込めるモナドの世界
一方で副作用とプログラムは切っても切れない関係です。
printですら副作用なのです。
関数型言語はこの矛盾をモナドという仕組みを利用して解決します。
モナドは副作用を起こしうる処理を包み込み、それを純粋関数の世界から副作用が実行可能な世界に運びこんでから実行するコンテナのようなものです。
コンテナは現実世界との接点でその副作用を実行します。
その他の純粋関数型部分では実行したい副作用をモナドの中に記録するコードしか書きません。
モナドのおかげで純粋関数型は純粋であり続けるのです。
副作用は世界の最果てへ
殆どの副作用コードは純粋な形に書き換えられます。
どうしても副作用を伴うものがIOです。
上で述べていたモナドは実はIOモナドなどと呼ばれたりします。
なぜならIOはプログラムの外の世界と通信し作用を与えるものだからです。
トートロジー的な表現ですが、プログラムの外の世界が変わっている以上副作用を起こさざるを得ません。
したがって副作用的な処理はプログラムと外の世界の接点に集まる傾向があります。
多くの場合プログラムの起動箇所であるmain関数に集約されます。
2つの概念が生み出すクリーンでピュアな世界
クリーンアーキテクチャは実装の詳細をプログラムの外側に追いやろうとするアーキテクチャスタイルです。
また関数型言語は副作用のある処理をプログラムの外側に追いやることを強制します。
上で述べたように実装詳細にはIO的な側面を持つものが多くあり、その殆どは副作用を生みます。
例えばhttpリクエスト、データベースアクセスなどは必ず副作用を起こします。
print、環境変数の読み出しなども副作用です。
つまり詳細を追い出したいクリーンアーキテクチャにとって関数型言語は非常に相性のいい相棒になりうるのです。
実際にこの組み合わせでコードを書いてみるとプログラムの方針部分から詳細が消え去るクリーンで純粋な世界が現れ感動します。
最後に
今回は関数型言語とクリーンアーキテクチャの相性の良さについて考察してみました。
このどちらも難しい概念であり、十分な理解・説明ができているか正直自身はないため、もしご指摘などあればコメントをください。
ただ自分なりに面白い説明ができたのではないかと思います。
この記事がクリーンアーキテクチャや関数型言語の理解に役立ち、面白いと思ってもらえたなら嬉しいです。