Overview
Righting Software を少しずつ読み進めていく中で第一部の 3~5章に書かれているソフトウェアの設計の「構造」と「組み立て」の内容が、今まで目にしてきた設計系の書籍やブログを読んできた中で一番腹落ちした内容 (*) だったので書籍に記載された構造についての自分なりのメモや考えたこと、及び Go で具体的に実装したサンプルをログとしてまとめておくためのエントリ。
*個人的には名著『Clean Architecture』よりもわかりやすい内容だと思った。
今回の学習内容は以下にまとめてある。
読書 Note
まず Righting Software に構造と組み立ての章に関して気になったところを簡単にまとめる。
ユースケースと要件
- 要件は必要な機能ではなく、必要な振る舞いを明らかにするものではなければならない。
- システムが何をすべきかではなく、システムがどのように動作しなければならないかを規定する。
必要な振る舞い
- 必要な振る舞い(= システムがなんらかの仕事を達成してビジネスに付加価値を与えるためにどうしなければならないのか?) を表現したものが ユースケース。
- ユースケースはシステム内のアクティビティの特定のシーケンスになる。
- ユースケースはエンドユーザーとシステムのインタラクションやシステムと他のシステムとのインタラクション、バックエンドの処理を記述できる。
表現方法
ユースケース図とアクティビティ図
ユースケース図
このレベルのユースケース図は簡単に記述できるし、図じゃなくても文章で簡単に記述できる。ただ、最初から図を書いた方がいい。
アクティビティ図
こちらを書籍で推奨しているのはこちら。
アクティビティ図は振る舞いの時間的な側面を捉えることができる(待ちや並列実行など)点もユースケース図よりも表現の幅がある。
階層化されたアプローチ
サービスの活用
階層を超える方法として望ましいのは サービスの呼び出し である。
サービスを使えば以下のようなメリットが得られる。
- スケーラビリティ
- セキュリティ
- サービス指向プラットフォームはどれもセキュリティを重視している。
- サービス間呼び出しにも認証認可が必要になり、なんらかの ID 伝播メカニズムを使うことになる。
- スループットと可用性
- サービスはキューを通じた呼び出しを受けつけることができることで、負荷の上限をオーバーする分の処理はそのままキューに貯めておく、という方法で膨大な数のメッセージを処理することができる。
- 応答性
- サービスであれば呼び出しをバッファリングして、システムが限界を超えることを避けることができる。
- 信頼性
- クライアントとサービス間では到達の保証、ネットワーク接続障害の処理、呼び出し順序の指定などに信頼性の高いメッセージングプロトコルを使うことができる。
- 整合性
- 結果整合性を保証する協調的なビジネストランザクションを使えば1つの作業に複数のサービスを参加させることができる。
- 呼び出しチェーンの過程でエラーが発生したら、作業全体をなかったことにする。
- 同期
- クライアントが複数の並行スレッドを使っていたとしても、サービスの呼び出しは自動的に同期される。
階層の種類
本書には以下の階層(レイヤー)があると書かれている。
- クライアント層
- プレゼンテーション層とも呼ばれる。
- エンドユーザーのユーザーアプリケーションを指すことが多い。
- ビジネスロジック層
*1. ユースケースの変動性は以下のように並行処理で実現されたユースケースが、ビジネスの変化により直列の処理が必要になった、というようなものがあげられる。
- リソースアクセス層
- リソース層
- ユーティリティ層
- ロギング、認証認可、pubsub など全てのシステムが横断で利用するものをまとめておくレイヤー。
その他
第3章前半で構造についての説明やガイドライン書かれていて、後半では拡張性やマイクロサービスのことも触れられている。
第4章では第3章で説明された階層や各コンポーネントの組み合わせ方(組み立て)について記載されている。 後半に記載してる Go のサンプルではその組み立て方もある程度参考にしている。
第5章では 3, 4 章で書かれている内容をベースにしたケーススタディになっている。
今回は構造についてまとめておきたかったので第3章の前半をベースにまとめているが、設計については第一部を通読するのは復讐も兼ねて勉強になると思う。
階層についての個人としての解釈・考察
各階層について
- クライアント層
- ユーザー及び、システムを使う側の最前面に露出するところなのでもっとも変動性が大きい。
- ビジネスロジック層
- リソース層
- ミドルウェアのクライアント部分に当たるので ifra 層などと呼称されるケースもあるレイヤー。infra レイヤーと書かれると馴染みのあるレイヤーだなと思う。
ユースケースとアクティビティ図の考え方について
各アクティビティがドメインの受け持つロジックに関心事があり、マネージャーはそのドメインロジックを協調させてユースケース(=ある要件に対してのソフトウェアの振る舞い)を実現するものと捉えると、階層構造をとるアプリケーションの捉え方が少し変わった。
概要で参照してる PullRequest にて実装した設計は Righting Software で言及されている階層と組み合わせを、 ユーザー登録のユースケースをベースにして 以下のようなシーケンスをイメージして実装している。
- ユースケース
- アクティビティ
これを図に起こすと以下のようなイメージになる。
まとめ
階層構造を取るアーキテクチャについてずっとわかったようなわからなかったようなところを行ったり来たりしていたが、『Righting Software』に書かれている構造と組み分けの章を読んでみて、アクティビティ図とセットで考えることでようやく雰囲気で理解していたカプセル化の意味を少し実感できた気がする。
後半のプロジェクトデザインの章については、時間があればまた別のエントリでまとめたいと思う。