現場で役立つシステム設計の原則 ch5 アプリケーション機能を組み立てる
ドメインオブジェクトを使って機能を実現する
アプリケーション層のクラスの役割
- 三層+ドメインモデル設計
- アプリケーション層は処理の流れの進行役・調整役
- アプリケーション層のクラスはアプリケーションサービスクラス、または単にサービスクラスとも
三層+ドメインモデルの構造をわかりやすく実装する
- フレームワークのすすめ
- 標準化
- アプリケーションの記述が簡単になり、かつ安定する
- JavaのSpring Framework等
@Autowired
で依存オブジェクトを自動注入できたりする
サービスクラスの設計はごちゃごちゃしやすい
- なぜ
- ドメインオブジェクトが貧弱
- プレゼンテーション層の関心事に振り回される
- データベースの入出力の都合に引きずられる
- アプリケーション層にこれらのロジックを書かない
サービスクラスを作りながらドメインモデルを改善する
初期のドメインモデルは力不足/ドメインモデルを育てる
- サービスクラスに業務ロジックを書きたくなる誘惑に負けない
画面の多様な要求を小さく分けて整理する
プレゼンテーション層に影響される複雑さ
- 利用者のニーズに応じると「何でも編集画面」になりがち
- 「何でも編集画面」の多様な要求をサービスクラスの1つのメソッドに押し込めると非常に複雑になる
小さく分ける/小さく分けたサービスを組み立てる
- 分割前
withDraw()
は複数のことをしている- 引き出し可能かの判定(参照)
- 引き出し実行(登録)
- 基本: 登録系/参照系を分ける
- BankAccountService(参照)
canWithDraw()
: 引き出し可能かの判定balance()
: 残高照会
- BankAccountUpdateService(更新)
withDraw()
: 引き出し実行(登録)
- 基本となるサービスクラス群を別のサービスクラス(シナリオクラス)で組み立てるのがよい
利用する側と提供する側の合意を明確にする
- 契約プログラミングの話
- 知ってるので略
シナリオクラスの効果
データベースの都合から分離する
データベースの入出力に引っ張られる問題
データベース操作ではなく業務の関心事で考える
- Repository使え
- メモリ上のドメインオブジェクトの保管と取り出しができる(架空の)収納場所
実際のデータベース操作とリポジトリを組み合わせる
- 【補】 Separated Interfaceパターン適用(PofEAA)