あなたは貧血やリッチドメインモデルがありますか?


リッチドメインモデルはドメイン駆動型設計の技術的部分である.それは多くのビルディングブロックで構成されていますが、モデルの別のビューを提示したいと思います.これはこのトピックの記事の多くのシリーズの一つです.

ディープシステム


データモデルはアプリケーションアーキテクチャを大きく決定する.単純なCRUDアプリケーションを使用すると、しばしば“エンティティを取得し、プッシュ”の口語の仮定を仮定することができます.この場合、データモデル、そのデータを管理するサービス層、APIインターフェイスは十分でしょう.
残念なことに、いわゆる深いシステムの場合、すなわちユーザインタフェースによって指定できないものの場合、UI上で見ることができるのは、システムで実行されるアクションを必ずしも反映しているわけではない.ビジネスロジック、統合、スケジューラ、バックグラウンドアクションの多くが下に実行されます.この場合、チュートリアルの大部分に現れる原始的なアプローチを使用すると、スパゲティコード、開発者の悲しみ、したがって、持続不可能なシステムで終わります.どのように意識的に賢明にアプローチするには?
貧血データモデルは、反パターンとしてマーティンFowlerによって2003年に定義されました.彼はこれがオブジェクト指向プログラミングと一致していないと強調しますが、むしろ手続き型プログラミングで.

“The anemic domain model is really just a procedural style design…”


しかし、この貧血のものは何ですか?

原始モデル


通常モデルを一般化する特大の実体は、通常、無関心なgetterとセッターでいっぱいの貧血モデルと呼ばれています.この問題は必ずしもリレーショナルデータベースアプリケーションとは限らない.ファッショナブルな(そして、どれほど素晴らしい)NoSQLデータベースの世界では、そのような実体はSQL実体とほとんど同一に見えるかもしれません、参照の代わりに、我々は入れ子にされたモデルを見ます.そして、それは旧約聖書(Goldenクラス)のサイズでJSONデータベースに終わります.
したがって、我々はより悪いかより良いデータベースがないということを覚えていなければなりません.
public class Order {
    private Long orderId;
    private LocalDate orderDate;
    private LocalDate orderShippedDate;
    private String orderStatusCode;
    private int orderTotal;
    private Long customerId;
    private String shipToName;
    private Long shipToAddressId;
    private String shipToPhoneNumber;
    private Long shippingOptionId;
    private Long paymentOptionId;
    // getters and setters
}
これは、アプリケーションで使用される実際のコードの例です-ここで何か良いですか?ない.
基本から始めましょう.

If you are calling two setters in a row, you are missing a concept (Oliver Gierke)


プログラミング言語を学ぶとき、我々は常にカプセル化について話します.データの変更を防止したい.ただし、クラスの動作を定義しない場合は、どのように状態を変更しますか?もちろん忘れました.セッターもあります.なぜ私たちはそれらを持っています、結局、我々は公共の場を使用することができます、そして、それは異なっていません、そして、両方のケースでカプセル化がありません:クラスは何でもすることができます、そして、誰でもクラスを操ることができます(ここにカプセル化または限られた責任がありません).
別の問題.モデルの与えられたドメインが動作する以上の一般化と無文脈.
ビジネスの仕組みを理解する.

以前のモデルでは、順序文脈が混ざり合っていました.そして、それはおそらく多数の依存関係を持つ異なったステータスを持っているかもしれません.実際、順序は上記のチェーンのように進化しています.商品を注文する際には、在庫の初期予約をしなければならず、与えられた要求を処理しなければなりません.注文が完了すると、我々はそれを梱包し、それを出荷することができるように倉庫に送信するには、加えて、我々は注文をお客様に送信される請求書を生成します.これらの文脈の各々は、それ自身のフィールド、条件、論理とカプセル化をします.
能力に注目してエンティティサービスを避ける
では、貧血モデルの効果は何ですか?
  • アプリケーションを維持/開発する問題は、ファジーロジック領域を超えて、多くの依存関係-大規模な結合
  • いわゆるゴールデンクラスで動作することでより悪いパフォーマンス
  • 多くのboolensまたはenumsでしばしば動作する複雑な論理
  • モデルの与えられたドメインが動作する文脈ではない
  • クラスは何でもできます、そして、誰でもクラスを操ることができます
  • Liskovルールの破壊-オブジェクトを使用して抽出.getd ()get ()
  • 意図不明
  • どのようなビジネスアクションがここで行われている-我々はそれを名前がないので、我々は知らない?
    そしていつ私はそのような方法を使いたいですか?私は何も混同しない?
    ヵ月で、私も、何がここで起こっているかについてわかっていますか?
    私はいくつかのより多くの値を設定することを忘れた場合?
    他の誰かがエンティティを管理し、どのようにして何をすべきかを指示します.通常、いくつかのSuperUtiService、MyFancyExecutionManagService -このような攻撃はありません.

    リッチモデル

  • 方法はその意図を表現する
  • ビジネス言語がコードになる
  • エンティティは不変ですが、setがなく、それが何をしなければならないのか
  • オブジェクトのメソッドは、我々がさらに忘れた何かを恐れずに再利用することができます
  • エンティティは自分自身を管理し、それがその状態を変更し、それを確認し、反応することができます

  • ドメイン駆動設計哲学は、豊かなドメインの概念に完全に適合します.以下にDDDに基づくプロジェクトを紹介します.
    ドメイン駆動型ライブラリを用いた図書館プロジェクト

    例によるDDD / 図書館


    問題空間戦略解析と様々な戦術パターンを持つ包括的ドメイン駆動設計例


    リッチなモデルのコンポーネント
  • 高い粘着力
  • 値オブジェクト
  • 有界文脈
  • イベント
  • 六角形の建築
  • 使用例
  • そしてもちろん、実用的なアプローチ
  • 次の記事で紹介します.ちょうど貧血モデルをバイパスして大幅にあなたの仕事の質を向上させることができます.ドメイン駆動型設計に近い