web-dev-qa-db-ja.com

DDDとMVC:「モデル」と「エンティティ」の違い

MVCの「モデル」の概念について、私はひどく混乱しています。現在存在するほとんどのフレームワークは、コントローラーとデータベースの間にモデルを配置し、モデルはほとんどデータベース抽象化レイヤーのように機能します。コントローラーがますます多くのロジックを実行し始めると、「脂肪モデルスキニーコントローラー」の概念は失われます。

DDDには、固有のIDを持つドメインエンティティの概念もあります。私が理解しているように、ユーザーはエンティティ(たとえば、一意のユーザーID)の良い例です。エンティティにはライフサイクルがあり、その値はアクションの過程で変化する可能性があります。その後、保存または破棄されます。

上記で説明したエンティティは、モデルがMVCであると想定されていたものですか?私はどれだけ外れていますか?

さらに混乱させるには、Repositoryパターンなどのその他のパタ​​ーンを投入します(おそらくそこにサービスを配置します)。リポジトリがエンティティとどのように相互作用するのかは明らかです-モデルとはどのように関係しますか?

コントローラは複数のモデルを持つことができるため、モデルは一意のエンティティよりも「データベーステーブル」ではないように見えます。

UPDATE:この投稿では モデルは知識のあるものとして説明されており、単数またはオブジェクトのコレクションにすることができます。つまり、エンティティとモデルはほぼ同じように聞こえます。モデルは、エンティティがより具体的であるすべてを含む用語です。値オブジェクトもモデルになります。少なくともMVCに関しては。多分???

だから、非常に大まかに言えば、どちらが良いですか?

「モデル」は本当にない...

class MyController {
    public function index() {
        $repo = new PostRepository();
        $posts = $repo->findAllByDateRange('within 30 days');
        foreach($posts as $post) {
            echo $post->Author;
        }
    }
}

またはこれは、DAOとしてモデルを持っていますか?

class MyController {
    public function index() {
        $model = new PostModel();
        // maybe this returns a PostRepository?
        $posts = $model->findAllByDateRange('within 30 days');
        while($posts->getNext()) {
            echo $posts->Post->Author;
        }
    }
}

これらの例はどちらも、上で説明したことを実行しませんでした。私は明らかに迷っています。入力はありますか?

55
Nathan Loding

エンティティ

Entityは、ビジネスロジックが動作する単一のアイテムであるオブジェクトを意味します。より具体的には、ある種のIDを持つオブジェクトです。
そのため、多くの人がORMマップオブジェクトをエンティティと呼びます。

一部のインスタンスは、データベース内の単一の行を表すクラスに対して「entity」と呼ばれます。

他の何人かは、これらのクラスのものだけを、ビジネスルール、検証、および一般的な動作も含む「エンティティ」と呼び、他の人々を「データ転送オブジェクト "。

型番

Modelは、アプリケーションのUI(= View)と制御フロー(= Controller)に直接関係しないものですが、データへのアクセス方法に関するものですアプリケーションの主要なデータ抽象化が機能します。

基本的に、何でも上記に適合するモデルにすることができます。

MVC

エンティティをMVCのモデルとして使用できます。これらは2つの異なることを意味しますが、同じクラスを両方とも呼び出すことができます。

  • Customerクラスは非常に多くの場合(通常)エンティティであり、アプリ内のデータアクセスの一部としても使用します。この場合、エンティティとモデルの両方です。
  • Repositoryクラスはモデルの一部である可能性がありますが、明らかにエンティティではありません。
  • ビジネスロジックレイヤーの途中で使用するが、アプリケーションの残りの部分には公開しないクラスがある場合、それはエンティティである可能性がありますが、MVCアプリの観点からは明らかにモデルではありません。

あなたの例

あなたのコード例に関しては、私は最初のものを好みます。
モデルは、アプリケーションのデータ抽象化の手段として使用されるクラスであり、「モデル」という接尾辞が付いた名前を持つクラスではありません。多くの人が後者のブロートウェアを検討しています。

名前に「Model」が付いていない場合でも、Repositoryクラスをモデルの一部と見なすことができます。

また、最初のコードを使用する方が簡単で、後でコードを理解する必要がある他の人にとっては、理解しやすいという事実も付け加えておきます。

46
Venemo

すべての答えは、さまざまなもののマッシュアップであり、単に間違っています。

DDDのモデルは、現実世界のモデルとよく似ています。何かの単純化と抽象化です。それ以上でもそれ以下でもありません。データやオブジェクトなどには何の関係もありません。それは単にドメイン部分の概念です。また、すべての複雑なドメインには、常に複数のモデルがあります。トレーディング、請求、ロジスティクス。

エンティティは「アイデンティティを持つモデル」ではなく、アイデンティティを持つオブジェクトです。

リポジトリは、1次レベルのキャッシュだけでなく、ドメインの一部でもあります。これは、メモリ内オブジェクトのような錯覚を与え、どこからでも(エンティティではなく)集合体をフェッチし、それらを保存します。つまり、オブジェクトのライフサイクルを維持します。

DDDの概念について話す場合は、まず基本を読んで知識を修正してください。このように ThinkDDD です。

10
Don Zampano

アプリケーションの「モデル」は、データを保持するビットです。ドメイン駆動設計の「エンティティ」は、私が正しく覚えていれば、アイデンティティを備えたモデルです。つまり、エンティティは、通常、データベースまたはファイルの「物理」要素に直接対応するモデルです。 DDDは2つのタイプのモデルを定義していると思います。1つはエンティティであり、もう1つは価値であり、これはアイデンティティーなしの単なるモデルです。

リポジトリパターンは、モデル/エンティティのインデックス付きコレクションの一種です。たとえば、コードで注文#13が必要な場合は、まずリポジトリにそれを要求し、そこから取得できない場合は、どこにいてもそれを取得してフェッチします。もしそうなら、それは基本的にレベル1のキャッシュです。モデルでの動作方法とエンティティでの動作方法に違いはありませんが、リポジトリのアイデアは、DDDの観点から、IDを使用してモデルをフェッチできるようにすることであるため、エンティティにのみ許可されますリポジトリ。

6
KennethJ

これは具体的にRuby on Rails)についてですが、議論はMVCとDDDに関するものなので、同じ原則と情報が依然として適用されます。

http://blog.scottbellware.com/2010/06/no-domain-driven-design-in-Rails.html

1
Derick Bailey

サービスとコレクションを使用した簡単なソリューション:

<?php
class MyController {
    public function index() {
        $postService = ServiceContainer::get('Post');
        $postCollection = $postService->findAllByDateRange('within 30 days');
        while($postCollection->getNext()) {
            echo $postCollection->current()->getAuthor();
        }
    }
}

編集:モデル(クラス)は、エンティティスキームの単純な表現です。モデル(オブジェクト)は単一のエンティティです。サービスはモデルで動作し、具体的なデータをコントローラーに提供しますs。どのモデルにもコントローラーはありません。モデルは独立しています。
もう1つの「側面」では、マッパーがモデルを永続化レイヤー(データベース、サードパーティのバックエンドなど)にマッピングします。

1
erenon