DDD Part2 Ch.4 ISOLATING THE DOMAIN

DDDデザインパターン勉強メモ

出典: 

Isolating the Domain

  • ソフトウェアは複数の部品からなる
  • 直接的に問題を解決する部品は得てして小さい

    • 重要さと、部品としての大きさとは一致しない
  • 「部分」を抜き出して考えてはいけない

    • 夜空の星座を見るときのように、「システム」としてとらえる必要がある
  • ドメインの目的を、その他の機能と分離せよ

    • ドメインの概念を、技術にしか関連しない概念と混同すること避ける
    • ドメインの視点を全く欠いてしまうことを避ける
  • この「分離」手法については、先駆者が大勢おり、よく踏み固められた道である
  • ドメインモデリングに適用するために、ドメイン駆動の見地から軽く再検討していく

LAYERED STRUCTURE

  • ビジネスロジックとその他のコードを混ぜるな

    • ビジネスロジックと関係ないコードは多岐にわたり、膨大

      • UI
      • DBアクセス
      • N/Wアクセス
    • ビジネスロジックをその他の膨大なコードに混ぜると…

      • 表層にすぎないUIを弄っただけで、ビジネスロジックが壊れたりする
      • ビジネスルールの変更が困難になる

        • UI,DBアクセス、N/W、諸々をしらみつぶしに調べないといけない
      • こうなると、せっかくモデルがあっても、モデル駆動でオブジェクトを作ることは困難になる
  • 複雑なタスクを処理するプログラムを作るには、関心事を分割して、個々に集中できるようにせよ

    • 同時に、複雑な相互作用を維持しなければならない
  • 業界が行き着いた分割方法: LAYERED ARCHITECTURE

    • いくつかの標準的なレイヤからなる
    • 同層か、下層レイヤのモジュールにしか依存しないという原則
    • 上層へのメッセージングは間接的な方法で
  • レイヤ分けの価値

    • 各レイヤがプログラムの特定の側面に特化する

      • 側面ごとにモジュール強度の高い設計ができる
      • 設計を実装に落とし込みやすくできる
  • レイヤの分け方は大体この4層

    • User Interface (or Presentation Layer)

      • 結果の出力
      • 入力の解釈
      • 他システムとの連携(他システム = ユースケース図の「アクター」)
    • Application Layer

      • この層がやること

        • ビジネス上意味のある事
        • 他システムとの連携で必要なこと
      • この層自体は仕事をしない。薄く保て

        • ビジネスルールや知識は下層のDomain Layerに持たせて、仕事を委譲
    • Domain Layer (or Model Layer)

      • 以下を表現する層

        • ビジネスの概念
        • ビジネスシチュエーションの情報

          • 「状態」として、この層で管理・利用される

            • 技術的にはDBに永続化されているかもしれないが
              外から見たらあくまでこの層で管理・利用しているように見える
        • ビジネスルールの表現
      • ビジネスソフトウェアの核心
    • Infrastructure Layer

      • 上層のヘルパ

        • アプリケーションのメッセージ送信

          • メール送信
          • FAX送信
        • データ永続化

          • DB
        • ウィジェットの描画

          • グラフィクスとか
  • 細かな違いはあるかも

    • UIとApplicationとがスパッと分けられない
    • Infrastructureが複数層ある
  • この分割は、モデル駆動設計の成否をきめる重要なこと

    • とにかく、Domain Layerを他層から切り離すこと

      • ドメイン層のオブジェクトが、ドメインモデルの表現に専念できるように
      • 他層から独立して成長していけるように
  • 分割による他の利点

    • 各レイヤの設計がきれいに
    • 保守コストが減る

      • 異なる更新頻度・更新目的のものを分けられるため
    • 分散システムへのデプロイが可能に

      • 各層ごとに別のサーバやクライアントに配置
      • コミュニケーションのオーバヘッドが最小になり、パフォーマンスが向上する
        (Fowler 1996)

Partitioning Online Banking Functionality into Layers

  • オンライン銀行システムの例

    • 送金機能

      • 2つの口座番号を入力または選択
      • 送金額を選択
      • 送金を開始
  • ビジネスロジック「借方は必ず対応する貸方をもつ」はドメイン層に置く

    • p.72の絵は、ドメイン層をレイヤ分けしないと生じる問題をほのめかしている

      • すべてが1枚の絵に描いてある

        • 送金リクエスト受信
        • ビジネスロジック
        • DBのトランザクション処理まで
      • ので、ビジネスロジックに集中できず(紙面も割けず)、大幅に簡略化されている
      • もしもビジネスロジックに集中でき紙面も割けるなら、もっとよいモデルを思い描けるだろう

        • 元帳オブジェクト
        • 借方/貸方オブジェクト
        • 金融取引オブジェクト

Relating Layers

  • 分けたレイヤをつなぐ

    • 上から下: 「普通に」

      • publicなインターフェースの呼び出し
      • 参照を保持

        • ずっと
        • 一時的
    • 下から上: 他の方法

      • コールバック
      • OBSERVER PATTERN (GoF)
  • UI、アプリケーション、ドメイン層を分ける考え方はMVCに端を発する

    • 1970代、Smalltalkの世界で最初に導入された
    • Fowler(2003) (たぶんPoEAAのこと)

      • MVCのバリエーションを多数扱っている
    • Larman(1998) (Applying UML and Patterns(実践UML)のこと)

      • MODEL-VIEW分離パターンの中で考察
      • APPLICATION COORDINATORパターンは、アプリケーション層をつなぐ一つの手法
  • 重要なのは、ドメイン層の分離が保たれ、他層のことを考えずに設計できること

    • これさえ満たせれば、レイヤのつなぎ方はぶっちゃけ何でもいい
  • インフラ層が自らアクションを起こすことは、通常ない

    • 上層からの呼び出し
  • インフラ層はドメイン層の下にあるので、ドメインに関する知識を持ち合わせていない

    • インフラ層は単にSERVICESとして技術的能力を給する

      • 単にデータのレコードを返す、単にメールを送る
  • SERVICEの抽象化

    • 「メッセージを送る」というSERVICE

      • メールで送る
      • FAXで送る
      • 【補】送らない。テスト用モジュール
    • 「どうやって」をカプセル化
    • 上層の呼び出し元は「いつ」送るかのみを気にする
  • すべてのインフラまわりがSERVICEで包まれるとは限らない

    • ドメインオブジェクトの基底クラスに機能を乗せることもありうる

      • 【補】LaravelのEloquent Modelなんかがそうか?
        全Modelの基底で、DBアクセス機能を有している

Architectural Frameworks

  • フレームワークに書き方を強いられることがある

    • J2EEのentity beansとか
  • 例えば、すべてのオブジェクトをentity beans派生にするのはやってられない

    • 性能と開発速度両面で良くない
  • 大きなオブジェクトのみentity beans派生にし、小粒なものは汎用のObjectを使うことでこれを回避
  • フレームワークは賢く使おうね、という話

    • 全機能使う必要はない

The Domain Layer Is Where The Model Lives

  • ドメイン駆動設計で必要な層はただ一つ、ドメイン層

    • 他の層はドメイン駆動開発と関係ない部分
  • ドメイン層は

    • ドメインモデルと、関連する設計要素の顕現
    • ビジネスロジックの設計・実装からなる
  • モデル駆動設計では、ドメイン層はドメインモデルの概念を反映したものになる
  • ドメイン層とドメインモデルとの一致のためには、余計な関心事を分離しておくことが前提条件

THE SMART UI “ANTI-PATTERN”

  • DDDと相容れないもの
  • 対比してみる
  • 例: シンプルなプロジェクト

    • シンプルな機能を提供
    • データを入力して表示するだけ
    • ビジネスルールほとんどなし
    • オブジェクトモデリングに長けた人材不在
  • レイヤードアーキテクチャを採用し、モデル駆動開発を試みると…

    • 学習曲線がキツい

      • 短時間にいっぱい覚えないといけない
    • 簡単な機能の開発にも長時間かかる
    • 時間がかかってるうちにプロジェクトが潰れるのがオチ
    • 時間があっても、チームにスペシャリストがいないと習得が大変
    • なんとか習得できても、できるのはシンプルなシステム
  • DDDは意欲的なプロジェクトに好適、チームメンバーにもスキルを要求する

    • すべてのプロジェクトが意欲的なわけではない
    • すべてのチームがスキル持ち合わせているわけではない
  • SMART UIを適用する

    • アプリケーションをUIごとに切り分け、ビジネスロジックと一緒にに混ぜる
    • 異教 —これまでと言ってることが違うじゃないか
    • 本書で紹介していくあらゆる手法は、レイヤー分けせずには使えない
    • 逆に、使わないならレイヤー分けする必要はない
  • SMART UIのadvantages

    • 簡単なアプリケーションにおいては生産性が高い
    • 能力の低い開発者でも少ない訓練で参加できる
    • 要求分析でしくじっても、プロトタイピングと素早い修正で乗り切れる
    • UIごとにアプリケーションが分かれているため、振る舞いを継ぎ足してアプリケーションを拡張していくのが容易
    • DBを通して完全性・一貫性を保てる
    • 4GL: 4th generation languages で書ける

      • 特定用途の言語
    • よくわかっていない保守プログラマでもコピペとかで保守できる
  • SMART UIのdisadvantages

    • DBを通さないと完全性・一貫性を保てない
    • 再利用や抽象化がない

      • ビジネスルールのコードが多重化する
    • 抽象化がないので、リファクタリングの選択肢が狭まり、プロトタイピングと反復が限界を迎える
    • 複雑で手に負えなくなる

      • 単純なアプリケーションを継ぎ足すことしかできなくなる
      • リッチな振る舞いを作りこむ余裕がなくなる
  • ありがちな失敗

    • チームで合意をとれていないのに洗練された設計アプローチを取り入れてしまい
    • 必要もないのに、複雑なインフラを導入し、強力なツールを使ってしまう
    • 4GLで十分なのに、柔軟な3GL(Javaとか)を使ってしまう
  • SMART UIの導入の結果

    • 全部捨てないと他の設計パターンに移行できなくなる
    • 一度SMART UIを選んでしまったら、それ用のツールを使うこと
    • 後からJavaを取り入れたところで、一度取り入れたSMART UIを変えることはできない

      • 実装コストがかさむようになるだけ
  • 逆に、モデル駆動開発も最初から取り入れなければならない

    • 最初はシンプルだとしても、まず孤立したドメイン層から始めること
    • さもないと、SMART UIのようににっちもさっちもいかなくなる
  • SMART UIとレイヤードアーキテクチャの中間くらいのもある

    • TRANSACTION SCRIPT by Fowler(2003)
    • UIとapplicationとを分離
    • ただしモデルオブジェクトは作らない?
  • ドメイン関連のコードを凝集度の高い形で分離し、他と疎結合にすることは、DDDをサポートするかもしれない

    • 【補】必要条件でも十分条件でもないということか。歯切れが悪い

Other Kinds of Isolation

  • インフラ層やUI層以外にも、ドメインモデルを台無しにするものはある

    • モデルをぼやかし、有用性を損なうもの

      • ドメインを構成する要素を、まだ完全にモデルに落とし込み切れていない
      • 同じドメイン・異なるモデルを扱う他のチームとの協業
    • ドメインモデルが超複雑
  • 本書の後のほうで扱う

英語

  • disproportionate

    • Too large or too small in comparison with something else.
  • sophisticated

    • Having, revealing, or involving a great deal of worldly experience and knowledge of fashion and culture.
  • diffuse

    • Spread over a wide area or between a large number of people.
  • meticulous

    • Showing great attention to detail; very careful and precise.
  • intricate

    • Very complicated or detailed.
  • cohesive

    • モジュール強度の高い
  • debit

    • An entry recording a sum owed, listed on the left-hand side or column of an account.
    • 借方
  • credit

    • An entry recording a sum received, listed on the right-hand side or column of an account.
    • 貸方
  • dumb down

    • [informal] Simplify or reduce the intellectual content of something so as to make it accessible to a larger number of people.
  • ledger

    • A book or other collection of financial accounts.
    • 元帳
  • pioneer

    • Develop or be the first to use or apply (a new method, area of knowledge, or activity)
  • intrusive

    • Causing disruption or annoyance through being unwelcome or uninvited.
  • judiciously

    • With good judgement or sense.
  • straitjacket

    • A strong garment with long sleeves which can be tied together to confine the arms of a violent prisoner or mental patient.
  • with tongue in cheek

    • not intended seriously; done or said as a joke
  • muster

    • Assemble (troops), especially for inspection or in preparation for battle.
    • Collect or assemble (a number or amount)
  • heresy

    • Belief or opinion contrary to orthodox religious (especially Christian) doctrine.
  • orthodox

    • Following or conforming to the traditional or generally accepted rules or beliefs of a religion, philosophy, or practice.
  • doctrine

    • A belief or set of beliefs held and taught by a Church, political party, or other group.
  • gospel

    • [in singular] The teaching or revelation of Christ.
  • revelation

    • surprising and previously unknown fact that has been disclosed to others.
  • bite the bullet

    • to force yourself to do something unpleasant or difficult, or to be brave in a difficult situation: