2012-03-15 19 views
7

ドメインエンティティごとに、データマッパーにAPIを提供するリポジトリがあるとします。例えば、私がUserEntityを持っていれば、ユーザデータをデータベースに保存するためにUserMapperに話すUserRepositoryがあります。新しいドメインエンティティを作成する場所はどこですか?コントローラ、リポジトリ、またはマッパー?

今、フォームがWebページに送信され、コントローラが送信された情報に基づいて新しいUserEntityを作成する必要があることがわかっているとします。に渡す人、

  1. は、その場ですぐそこに新しいUserEntity()を行うと、送信されたフォームデータに応じて、必要なすべてのsetterメソッドを実行し、その後、レポにUserEntityを渡す:

    はそれがありません挿入のためのマッパー?

    コントローラが作成UserEntity =>レポ=>マッパー=> DB

  2. 配列にフォームデータをオンにし、新しいUserEntity()とセッターを実行UserRepositoryに渡し、且つに渡し

    挿入のためのマッパー?

    コントローラは、ユーザデータを渡す=>レポはUserEntity =>マッパー=> DB

    を作成
  3. 新しいUserEntityと挿入するためマッパーに配列を通過UserRepositoryに配列を渡しますか?

    コントローラは、ユーザデータを渡す=>レポは、ユーザデータを渡す=>マッパーは誰の責任、それはオブジェクトの作成を管理することであるUserEntity => DB

を作成しますか?

答えて

1

これは答えが難しい質問です。私の2セントは2つの理由から1番です。まず、エンティティにドメインの検証があると仮定して、渡されるデータを非常にうまく拒否することができます。それが2または3のいずれかで起こるならば、あなたは拒絶の前にいくつかのオブジェクトを深く見つけました。 2/3と1の違いについては、メモリや実行時間はそれほど多くないかもしれませんが、それは違いです。私は速く失敗しようとします。

第2に、私はコントローラがオブジェクトと同様に渡されるデータについて知っていることは完全に容認できると思います。私は "脂肪モデル、スキニーコントローラ"に同意するが、コントローラがエンティティについて知ることができないと言ってコントローラを作成しているtoo私の好みのためにスキニー。

+0

それは状況の素晴らしい分析です。私は他の考えを聞くことが好奇妙ですが、私は確かにコントローラでそれを作成するために受け入れられると思います。しかし、たぶん融通性が低いでしょうか?たとえば、DBのUserテーブルに新しいフィールドを追加すると、UserEntitiesを作成する各Controllerに移動する必要があります。 – johnnietheblack

+0

新しい情報を受け入れるビューを編集している可能性は非常に高いです(従来のWebアプリケーションについて話していると仮定して)、コントローラを編集するのはそれほどのストレッチではありません。あなたがビューを編集するのを忘れたコントローラを編集するのを忘れていた可能性があります。また、単純なグローバル検索では、クラスが使用されている場所を見つけることができます。 – Crashspeeder

+0

もう一つの良い点は、コントローラが答えであれば、私は動揺していません...しかし、まだ、いくつかの場所で同じインスタンシエーションプロセスを記述する "有罪"と感じる私の一部があります。いいえ?同様に、新しいテーブルの変更を反映するフォームフィールドを追加するためには、1つのファイルだけを変更する必要があるように、ビューを設定しました。 – johnnietheblack

2

私はこの質問が古いことを知っていますが、唯一の回答は公式には受け入れられておらず、これは将来のサーチャーに役立つかもしれないので、あなたの質問に直接答えるには、私は上記のどれも言っていないでしょう。私はコントローラとrepo/mapperオブジェクト間のやりとりを仲介するために、余分なサービス、もしあれば "マネージャー"を持っていることを好みます。各モデルには、作成、更新、および削除を処理する専用のマネージャがあります。

コントローラ

私はアプリケーションの接着剤としてのコントローラを考えます。私たちが望むすべての懸念をできるだけ多くの部分に分けることができますが、ラインのどこかでは、ビュー側とモデル側の両方を理解する必要があり、そのオブジェクトがコントローラです。コントローラの唯一の実際の仕事は、リクエストをレスポンスにマッピングすることです。どんな種類の中間処理も別の場所で開始されるべきです。

CRUDアプリでは、新しいオブジェクトのインスタンスを作成してコントローラに保持するのはかなり簡単です。貼り付けるのは数行しかないので、複数回行ってもそれは簡単です。オブジェクトの作成が簡単ではない場合はどうなりますか?私は多くの複雑な関係を持つアプリケーションを維持しており、ユーザーが投稿した作成は多くの場合同時に多くのオブジェクトの作成を必要とします。これはコントローラとモデルのみの環境では維持できません。 FormHandlerとマネージャー:

エキストラサービスレイヤー

これを処理するためには、私は2つの余分なサービスレイヤを作成しました。フォームが送信されるたびに、フォームの内容がフォームハンドラレイヤに送信されます。フォーム・ハンドラーは、フォーム・データの理解と正規化を担当します。フォームハンドラは、適切なマネージャオブジェクトにデータを渡して処理することができます。マネージャオブジェクトはデータを処理し、ドメインレイヤを更新します。モデルの作成、モデルの変更、バックエンドへの永続化を担当します。

このように、コントローラはRequest、Response、Form(おそらく、フレームワークがサーバー側のフォーム作成をサポートしている場合)、FormHandlerの知識を持っています。フォームハンドラは、フォーム(またはフォームデータ)とマネージャの知識を持っています。マネージャは、リポジトリ、マッパー、およびモデルに関する知識を持っています。現在、マネージャはモデルとマッパーとの対話の唯一のポイントであり、フォームデータまたはリクエストまたはレスポンスについての知識はありません。逆に、コントローラとフォームハンドラはドメインレイヤのデータや永続性について知る必要はありません。

この設計では結論

:私が見つけた

Controller -> FormHandler -> ModelManager -> Mapper

はすべて私のクラスになりましユニット・テスト可能なため、うまくている関心事の分離に(ある程度でもコントローラ)です分割され、相互作用の単一のポイントは、重複するロジックを避けるための恩恵です。

ノート

私の心の中のレポが唯一のデータベースを照会するためである - それは何かを持っている場合は新しいものを作成していない、それを尋ねます。

この場合、私の経験では、symfonyの2とDoctrineを使用してからである

YMMV。例えばフォームレイヤは不要ですが、フォーム/ビューデータからドメインモデルが理解できるものへのデータ変換には非常に便利です。

関連する問題