「Clean Architecture 達人に学ぶソフトウェアの構造と設計」(日本語版)(以下、本書)
から得た視点についてまとめました。
要点
要点を先に述べると以下になります。
「変更に強い設計」とは
目的「保守コストの最小化」
核心「ビジネスルールの保護」
手段「依存の方向の制御」
まとめ
※注:冒頭に「まとめ」を述べ、その後に詳細を説明する形式となっております。
本記事では、「Clean Architecture」が目指す「変更に強い設計」について、依存関係の図を通して理解します。一見複雑に見える設計原則も、その根底にある目的から見るとシンプルになります。
目的は「保守コストの最小化」: ソフトウェアアーキテクチャの目的は非機能要件への対応です。特にシステムの構築と保守にかかる人的リソースを最小限に抑えることが重要です。
核心は「ビジネスルールの保護」: システムの価値の源泉である「ビジネスルール」は、UIやデータベースといった技術的詳細よりも変化しにくい資産です。この大切な資産を、移り変わりの激しい外部要因から隔離することが重要です。
手段は「依存の方向の制御」: そのために、SOLID原則の一つである「依存性逆転の原則」を用います。インターフェースを介して依存の方向を逆転させ、すべての矢印がビジネスルールに向かうように設計します。
これにより、データベースを切り替えたり、UIのデザインを変更したりといった技術的な変更が、システムの中心であるビジネスロジックに影響を与えなくなります。
さらにビジネスロジックへ優先的にテストやリファクタリングといった工数を投資することで、結果として、修正は迅速かつ安全になり、長期的な保守コストを抑えることができます。1
クリーンアーキテクチャやドメイン駆動設計、SOLID原則、さらにドメイン駆動設計、これらの概念は、共通の目的でつながっていると理解できます。
第1章からの引用します。
ソフトウエアアーキテクチャの目的は、求められるシステムを構築・保守するための必要な人材を最小限に抑えることである。
処理クラスとコンポーネントの依存関係の図
クリーンアーキテクチャの同心円の図もよいのですが、私が理解を深めるきっかけは、この依存関係の図でした。
第8章 オープンクローズドの原則
>図8-2 処理をクラスに分割し、クラスをコンポーネントにまとめる
この図の最も重要なポイントは一つだけです。
「すべての依存の矢印が、中心であるInteractorに向かっている」
(補足)
- 複数の処理クラスを囲む枠がコンポーネント
- 通常の矢印が「使用」の関係
- 白抜き矢印が「実装や継承」の関係
以下、冒頭のまとめに至った経緯を順を追って説明します。
高速道路から降りて下道をすすむようにスピード感が変わりますのでご注意ください。
なぜルールに従うだけで「変更に強く」になるのか?
「第22章 クリーンアーキテクチャ」
有名なクリーンアーキテクチャの同心円の図がある章です。
この章の最初と最後をつなげると1つのメッセージが見えてきます。
まとめの部分
ルールを守っていれば、いずれ多くの苦痛から解放してくれるだろう
システムの外部のパーツ(データベースやウェブフレームワーク)が廃れても、(中略)最小限の労力で置き換えられる
とあります。
なぜ単純なルールを守れば「最小限の労力」となるのか?
冒頭の部分
その答えは、章の冒頭に書かれていました。
いずれも「関心事の分離」という同じ目的を持っている。
つまり「関心事の分離」によって「最小限の労力で置き換えられる」と読めます。
関心を分離する「手法」:依存の矢印を逆転させる
では「関心事の分離」とは具体的にどうすればよいのか。
それは冒頭にあげた「第8章 オープン・クローズドの原則」の図です。
コンポーネントとクラスがあり、それぞれの依存を矢印で表現しています。
この図の最も重要なポイントは一つだけです。
「すべての依存の矢印が、中心であるInteractorに向かっている」
なぜInteractorを矢印(依存)の中心(最上流)として設計するのか。
依存の方向を整える
開発では、単一責務の原則によりクラスを分けていきますが
通常、処理の流れに沿って依存関係を作ります。
しかし図ではインターフェース(図の白抜き矢印)を使って、一部の矢印の向きを逆転させています。
SOLID原則の一つである「依存性逆転の原則」ですね。2
これにより、外側のコンポーネント(ViewやDatabaseなど)を変更しても、その影響が中心のInteractorに及ばなくなります。
つまり変更の影響範囲が限定されます。
その結果、コードの読解やテストのコストが下がり「最小限の労力」で変更が実現できます。3
そうです。8章と22章は
「関心事の分離」によって「最小限の労力で変更できる」
という共通のメッセージが含まれているのです。
なぜInteractorが中心なのか?:ビジネスルール
8章には以下の説明があります。
なぜInteractorがそんなにも特権的な位置づけになるのだろう?それはビジネスルールを含んでいるからだ
そうですビジネスルールです。
本書の内容を飛び越えてしまいますが、ドメイン駆動設計でいうコアドメインやユースケースといった「複雑な業務ロジック」と同じですね。4
ビジネスルール(複雑な業務ロジック)を依存の最上流にするという視点を得ました。
memo:
もちろん、ビジネスルールそのものが不変というわけではありません。
市場の変化によって新しい割引ルールが追加されたり、法律の改正で計算方法が変わることもあります。
しかし、そうした変更はシステムの中心的な関心事であり、UIの見た目やデータの保存方法といった技術的な詳細の変更とは性質が異なります。
クリーンアーキテクチャは、この本質的なビジネスロジックの変更に集中しやすくするための設計なのです。
クリーンアーキテクチャの同心円の図と冒頭の図の共通点
材料がそろいました。仕上げに入ります。
22章の同心円の中心、8章のInteractor、そしてドメイン駆動設計本にあるコアドメイン
これらは「分離して依存(矢印)の方向を揃えることで「変更」の影響範囲を最小化する」という点で共通しています。
「変更の影響が最小化する」とは言い換えると「必要な人材を最小化できる」ということです。
これは本書の序盤にある「目的」とも合致します。
ソフトウエアアーキテクチャの目的は、求められるシステムを構築・保守するための必要な人材を最小限に抑えることである。
そうです。バラバラだった以下のような要素、
「オープンクローズドの原則」「依存関係逆転の原則」「同心円の図」「コアドメイン」「複雑な業務ロジック」
それらが、すべて1つの目的につながっているという視点を得ました。
私の中で抽象的だった知識がつながり「腹落ちした」感覚を得た瞬間です。
理解を助ける視点の切り替え
蛇足ながらもう1点。視点の切り替えが重要な役割を果たしました
クリーンアーキテクチャの価値は、「変更」を前提とすることで初めて理解できます。
しかし私は当初、「データベースなんてそう頻繁に変更しない」と考えた結果、内容の理解が進みませんでした。
ここで視点を切り替えることで、理解がすすみました。
- データベース: 新規導入は稀でも、セキュリティパッチの適用やバージョンアップ対応は頻繁に発生します
- ウェブフレームワーク: 技術トレンドの移り変わりが激しく、数年単位での置き換えは十分に考えられます
- システムの規模: システムが大きく、長期間運用されるほど、変更の機会は増えていきます。
「変更が少ない小規模なツール」を想像すると、クリーンアーキテクチャは過剰な設計に見えるかもしれません。
しかし「変更が多い大規模なシステム」を想像すれば、その価値はあがります。
このように視点を切り替え、自分の中で具体例を想像することが、深い理解への近道だと気づきました。
これからは、ソースコードでinterface
を見かけたときも、慌てずに「ああ、これは変更に備えて、依存関係を整理しているんだな」と、その設計意図を読み解けるようになるはずです。
最後に
コードを読むとき、あるいは新しい機能を設計するとき、この「依存の矢印」を意識してみてください。
目の前のコードが、クリーンアーキテクチャの同心円で理解できるかもしれません。