勉強日記

チラ裏

現場で役立つシステム設計の原則 ch5 アプリケーション機能を組み立てる

gihyo.jp


ドメインオブジェクトを使って機能を実現する

アプリケーション層のクラスの役割

三層+ドメインモデル設計

  • アプリケーション層は処理の流れの進行役・調整役
  • アプリケーション層のクラスはアプリケーションサービスクラス、または単にサービスクラスとも

三層+ドメインモデルの構造をわかりやすく実装する

  • フレームワークのすすめ
    • 標準化
    • アプリケーションの記述が簡単になり、かつ安定する
  • JavaSpring Framework
    • @Autowiredで依存オブジェクトを自動注入できたりする

サービスクラスの設計はごちゃごちゃしやすい

  • なぜ
    • ドメインオブジェクトが貧弱
    • プレゼンテーション層の関心事に振り回される
    • データベースの入出力の都合に引きずられる
  • アプリケーション層にこれらのロジックを書かない

サービスクラスを作りながらドメインモデルを改善する

初期のドメインモデルは力不足/ドメインモデルを育てる

  • サービスクラスに業務ロジックを書きたくなる誘惑に負けない
    • 【補】 strategic mindset vs. tactic mindset(APoSD)
    • ドメインモデルを育てる絶好の機会
      • 適切なドメインオブジェクトがなければ追加する
      • ニーズにぴったり合っていなければ改良
        • リネーム
        • メソッドの追加

画面の多様な要求を小さく分けて整理する

プレゼンテーション層に影響される複雑さ

  • 利用者のニーズに応じると「何でも編集画面」になりがち
  • 「何でも編集画面」の多様な要求をサービスクラスの1つのメソッドに押し込めると非常に複雑になる

小さく分ける/小さく分けたサービスを組み立てる

  • 分割前

分割前

  • withDraw()は複数のことをしている
    • 引き出し可能かの判定(参照)
    • 引き出し実行(登録)
  • 基本: 登録系/参照系を分ける

分割後

  • BankAccountService(参照)
    • canWithDraw(): 引き出し可能かの判定
    • balance(): 残高照会
  • BankAccountUpdateService(更新)
    • withDraw(): 引き出し実行(登録)
  • 基本となるサービスクラス群を別のサービスクラス(シナリオクラス)で組み立てるのがよい

利用する側と提供する側の合意を明確にする

シナリオクラスの効果

データベースの都合から分離する

データベースの入出力に引っ張られる問題

  • 業務の関心事がRDBCRUDに変換され、プログラム上から業務の意図が消えがち
    • 要件変更時に苦労する

データベース操作ではなく業務の関心事で考える

  • Repository使え
    • メモリ上のドメインオブジェクトの保管と取り出しができる(架空の)収納場所

実際のデータベース操作とリポジトリを組み合わせる

  • 【補】 Separated Interfaceパターン適用(PofEAA)

サービスクラスの記述をデータベース操作の詳細から解放する

  • サービスクラスにRDB操作の詳細を意識させない
    • 【所感】意識しなくて済む分は、という但し書きつき