はじめに
最近、「ちょうぜつソフトウェア設計入門」を読んでいるので、本書の中で自分が疑問に感じたポイントをQ&A形式で振り返ってみたいと思います。
この記事では、各セクションの簡単な説明の後に、[Q]で疑問に感じたこと、[A]で調べてわかったことをまとめています。
なお、サンプルコードにPHPを使用していますが、言語を問わず広く有効な設計手法なので、他言語でも応用できる内容になっています。
それでは、第1章を振り返りながら、一緒に「ソフトウェア設計」について学んでいきましょう!
依存の向きと安定度
意味関係の強さや実際のコードのつながりのまとまり具合を凝集度と呼びます。
無駄な癒着がなく、しっかりとつながりが切れていることを疎結合と呼びます。
一般的には、疎結合なものは凝集度を上げやすくなるという相関関係があります。
ソフトウェアのモジュールは必ず何かとつながっています。
あるモジュールAが別のモジュールBを使っているとき、「AはBに依存する」と言います。
依存関係はこの向きをとても重視します。
AはBがないと成立しませんが、BはAがあるかないかにかかわらず成立します。
[Q]
モジュールが他のモジュールに依存して密に結合すると、いったい何が問題なのでしょうか?
[A]
密結合の問題点は、自身を変更していなくても、依存するモジュールに変更が入ったら、自身を変更したのと同じリスクを負うことです。
依存の実動作に違いが起きていることもあれば、場合によっては、クラス名が変わっていたり、メソッドの引数順序が変わっているおそれもあります。
変更影響は、依存の方向とは逆向きに、使っている箇所を子孫末代まですべて巻き込みます。
どうすればクリーンになるのか
ある変更が別の余計な変更を招くのが汚いアーキテクチャの特徴でした。
クリーン=きれいな状態とはつまりその逆、他の構造部分に期待されない影響が及ぶ可能性を最小化した設計=デザインがなされた状態です。
クリーンアーキテクチャを象徴する図はこんなかたちをしています。
1層目「ドメインモデル」
ユーザーがどんな操作をしたいかとは無関係に、普遍的に存在する本質を入れます。
この領域は、プログラミング言語の文法と標準ライブラリ以外の何にも依存しないように記述します。
ソフトウェアで扱うことの本質が根本的に変わらないかぎり、一度安定すればなかなか変わることはありません。
正確には、変わらないことだけを意図的に抽出して入れることで、中立さを洗練させていくと表現するのが合っています。
2層目「ユースケース」
ユーザーが行いたい操作を表現するロジックを、内側からもうひとつ外の円に入れます。
この部分はユースケースと呼ばれる領域です。
ユースケースはユーザーの要望によって変化します。
改善の余地があるということは、少し不安定だということです。
しかし、ユースケースは安定した(させた)ドメインモデル以外への依存がありません。
後から技術的な理由で変更を強いられる可能性がほぼないので、求めている機能が明確になれば、かなりの安定度を期待できます。
3層目「インターフェースアダプター」
ソフトウェアをユーザーに使ってもらうには、実際に実行できるアプリケーションとして形にしてやらなければなりません。
それが3つ目の円の役目です。
ユースケースの表現に適したデータや語彙を、コンピュータが扱うのに適したデータと語彙に言い換える役目を指してインターフェースアダプターと名付けられています。
3層目にあるコードは、実現したいユースケースにどんなものがあるかを知っています。
つまり、2層目に依存するわけです。
コントローラーはそれぞれのユースケースを参照しつつ、入力から出力までのコンピュータの制御の流れを、技術的な概念コードで表現します。
4層目「インフラストラクチャ」
しかし、まだそれでは完全に動作するアプリケーションにはなりません。
実際の入出力の詳細や画面とのつなぎ込みといった、具体的な技術的問題の解決を含まないからです。
それらは、もっとも外側の4つ目の円に小刻みに配置します。
横のつながりのない数多くの独立したモジュール群にそれぞれ、データベース接続のみ、メール送信のみ、といった役割を振り分け、閉じて、外部とのやりとりをする技術に関心を向けます。
自分の預かり知らない技術の事情に影響されるため、4層目はかなり不安定になります。
が、処理内容ごとに小分けになっているため、他の部分への影響は比較的少なくなります。
[NOTE]
クリーンアーキテクチャが言っているのは、どんな場合でも共通して、おおまかに4つほどのグループに分けられそうだというアドバイスです。
- 人がなんと言おうと事実な部分(ドメインモデル)
- 人が何をしたいかの部分(ユースケース)
- アプリケーションの枠組みづくり(インターフェースアダプター)
- 下支えとしての動作の実体(インフラストラクチャ)
おわりに
今回は、「ちょうぜつソフトウェア設計入門」の第1章を題材に、自分が疑問に感じたポイントを紹介しました。
「依存の向き」や「安定度」を意識することで、設計の見え方が少し変わってくると思います。
ぜひ皆さんも、自分のプロジェクトで“どちらがどちらに依存しているか”を意識して見直してみてください!
今後も読み進めながら、気づきがあればこうした形でまとめていきたいと思います!