鵜呑みにしないで! —— 書籍『クリーンアーキテクチャ』所感 ≪null 篇≫
はじめに
最近よくクリーンアーキテクチャが話題になってて、関心が高まってる感じしますよね!
ということでカブク社内でも書籍『クリーンアーキテクチャ』の輪読会が開催されました!
この記事は null 個人の考察です。
クリーンアーキテクチャとは
書籍を読んでみた結果、次のブログ記事がすべてだと言っていいと思いました。
- クリーンアーキテクチャ(The Clean Architecture翻訳) | blog.tai2.net
https://blog.tai2.net/the_clean_architecture.html
上記ブログ記事に比べて書籍に含まれる文字数は膨大ですが、膨大なのは前提知識(プログラミングパラダイムとか設計原則とか)と歴史と補足(と著者のカタルシス)です。
以下の私の記述は基本的に上記ブログ記事に対する考察と取っていただいても差し支えありません(ただし引用文は書籍からの拝借です)。
矛盾
「ビジネスルール」を「フレームワーク」「UI」「データベース」など(以下、書籍内の言葉を借りて「外部エージェント」と呼びます)に依存させたくない…
これはビジネスルールの保守性を重要視するソフトウェアの設計においてとても自然な欲求のように思います。
これを実現するためには、ビジネスルールと外部エージェントとの間に立ってデータの受け渡しや変換・実行制御を行うための中継役が必要になりますよね。クリーンアーキテクチャではこの中継役がインターフェイスアダプターという名前のレイヤーとして登場します。
インターフェイスアダプター
インターフェイスアダプターのレイヤーのソフトウェアは、ユースケースやエンティティに便利なフォーマットから、データベースやウェブなどの外部エージェントに便利なフォーマットにデータを変換するアダプターである。たとえば、GUIのMVCアーキテクチャを保持するのはこのレイヤーになる。プレゼンター、ビュー、コントローラーは、すべてこのインターフェイスアダプターのレイヤーに属している。モデルは、コントローラーからユースケースに渡され、ユースケースからプレゼンターとビューに戻されるデータ構造にすぎない。
同様に、このレイヤーでは、エンティティやユースケースに便利な形式から、永続フレームワーク(つまりデータベース)に便利な形式にデータを変換する。円の内側のコードは、データベースについて何も知らない。データベースがSQLデータベースであれば、すべてのSQLはこのレイヤー(特にデータベースに関係する部分)に限定する必要がある。
また、このレイヤーには、外部サービスなどの外部の形式から、ユースケースやエンティティが使用する内部の形式にデータを変換するアダプターも含まれる。
ビジネスルールと外部エージェントとの橋渡しを行う中継役は、ビジネスルール・外部エージェント双方を知っている必要があります。
クリーンアーキテクチャが革新的なのは、インターフェイスアダプターが外部エージェントに依存しないと謳っているところでしょう。
図22-1 クリーンアーキテクチャ
依存性のルール
図22-1 の同心円は、ソフトウェアのさまざまな領域を表している。一般的には、円の中央に近づくほどソフトウェアのレベルが上がっていく。円の外側は仕組み。内側は方針である。
このアーキテクチャを動作させる最も重要なルールは、依存性のルールである。
ソースコードの依存性は、内側(上位レベルの方針)だけに向かっていなければいけない。
円の内側は外側について何も知らない。特に、外側で宣言された名前は、内側にあるコードで触れてはいけない。これには、関数、クラス、変数、そのほかの名前付きソフトウェアエンティティが含まれる。
同様に、外側で宣言されたデータフォーマットは、内側から使ってはいけない。外側のフレームワークで生成されたフォーマットは特にそうだ。円の外側にあるものから内側にあるものに影響を及ぼしたくはない。
外部エージェントに依存することなく「ユースケースやエンティティに便利なフォーマットから、データベースやウェブなどの外部エージェントに便利なフォーマットにデータを変換する」ことは果たして可能でしょうか?
外部エージェントに便利なフォーマットへデータを変換しておきながら、 “あ、あんたなんかに依存してるわけないでしょ! あんたのことなんか知らないんだからっ!” ってそれ…
インターフェイスアダプター(イメージ)
はっきり言ってしまいましょう。ツンデレです。じゃなくて、矛盾です。インターフェイスアダプターは外部エージェントについてよく知っている必要があり、この依存関係は逆転のしようがありません。したがって、 依存性のルールとインターフェイスアダプターの定義とが矛盾しています。
外部エージェントとインターフェイスアダプターとの依存関係を逆転できると勘違いする人がいるようです。インターフェイスアダプターには SQL さえも記述すると言っているのに、ですよ。もちろん、ものによっては、インターフェイスアダプターのレイヤーに抽象インターフェイスを用意して外部エージェント側で具象化することで、ソースコード上は依存関係が逆転しているように見せかけることもできるでしょう(一般に外部インターフェイスには「多くのコードは書かない」とのことですが、書こうと思えばの話です)。ですが、インターフェイスアダプターの役割的に、外側に何があるのか全く知らない状態では実装できません。これに対して、ユースケースはインターフェイスアダプターや外部エージェントについて全く知らない状態で実装できます(たとえば [Web フロントエンド] 状態更新ロジックをフレームワークから独立させる | Kabuku Developers Blog ではユースケースからフレームワーク(外部エージェント)を抽象化しており、実際に Angular と React とでユースケースのロジックを使いまわしています)。勘違いする方はこの違いがわからないのではないでしょうか。見かけの依存関係を逆転したところで、意味的な依存関係が逆転することは決してなく、それは単なる難読化でしかありません。
矛盾を解消するには、「インターフェイスアダプターの定義」「依存性のルール」のどちらかを変更しなければなりません。「インターフェイスアダプターの定義」を変更するとソフトウェアとして成立しなくなりそうなので、「依存性のルール」を変更する方が現実的でしょう。すなわち、 「ソースコードの依存性は、同じ方向とは限らない。」 というルールなら無矛盾になります。(しかしこれではノールールですね… よりまともなルールを考えてみてください。)
依存性のルールはクリーンアーキテクチャをクリーンアーキテクチャたらしめる核であり、依存性のルールを変更したアーキテクチャはもはやクリーンアーキテクチャではないと言えるでしょう。依存性のルールの変更が矛盾を解消するための現実解であることと合わせると、次の結論が導かれます。
クリーンアーキテクチャに則ったソフトウェアシステムは構築できません。
「クリーンアーキテクチャを勉強してみたけど 私にはむずかしくて実践できそうにない」と感じた方がいらっしゃるかもしれませんが、実際、誰がどうがんばっても実践できないので、安心して諦めていただきたいと思います。
クリーンアーキテクチャむずかしくて実践できないよ
クリーンアーキテクチャに則ってソフトウェアシステムを構築したと謳う記事を見かけますが、実際にソフトウェアとして機能しているとすればそれはクリーンアーキテクチャではなくオレオレクリーンアーキテクチャに則って構築されたのだと言えるでしょう。たとえば次のようなオレオレクリーンアーキテクチャが考えられます。
- インターフェイスアダプターが外部インターフェイスに依存している
- 本来「インターフェイスアダプター」であるはずの中継役を「外部インターフェイス」レイヤーに置くことで、中継役が外部インターフェイスとの境界をまたいでいないことにしている
このうち 1. は普通に使える普通のアーキテクチャだと思います。依存ルールがクリーンアーキテクチャと異なることに自覚的であれば尚良いのですが。一方 2. は書籍『クリーンアーキテクチャ』に「典型的なシナリオ」の例として登場する欺瞞です。とても腹立たしいです。存在するはずの境界を隠蔽することでレイヤーごとの関心事を不明瞭にする本末転倒なオレオレアーキテクチャだと言えるでしょう。
まとめ
ソフトウェアアーキテクチャ設計の目的はメンテナンスしやすいソフトウェアシステムの実現であって、クリーンアーキテクチャはその雛形の 1 案でしかないことに注意しましょう。名前付けられたアーキテクチャがソフトウェアエンジニアの共通語として普及することには大きな価値があるものの、クリーンアーキテクチャの実践そのものを目的としてしまっては手段と目的を取り違えていると言わざるを得ません。
クリーンアーキテクチャには矛盾が含まれており、クリーンアーキテクチャに則ったソフトウェアシステムは構築できないことを指摘しました。クリーンアーキテクチャの解説は曖昧な自然言語で書かれたものですから、矛盾しないような解釈もできるかもしれません。「ここは文字通り受け取ると矛盾するけど、こう解釈すれば意味が通るぞ!」といった忖度は意識的にも無意識的にも起こり得ます。ですが、個々人の忖度に委ねられる部分があればあるだけ、エンジニア同士の共通認識は構築できず、むしろ混乱の元となります。矛盾しているように見えるアーキテクチャを解釈でどうこうするより、もっと理解しやすく実践しやすいアーキテクチャを考える方が有益ではないでしょうか。(クリーンアーキテクチャの知名度を考えると強く言い切れないのが歯痒いところですが…)
おわりに
この記事が議論のきっかけになれば幸いです!
この記事を鵜呑みにせず、ぜひご自身で読んで理解してくださいね!
カブクではソフトウェアエンジニアを募集しています!
カジュアル面談ではカブクという会社についてご説明させていただきます! オンライン面談も可! 応募するしないは説明を聞いてから検討してみて!
その他の記事
Other Articles
関連職種
Recruit