19

DAOパターンに関する多くの情報を調べて、その要点を理解しました。しかし、ほとんどの説明が全体像を伝えているわけではないように感じます。つまり、実際にDAOをどこで使用するのでしょうか。たとえば、Userクラスとそれに対応するUserDAOがあり、ユーザーを保存および復元できる場合、これは正しい方法です。

  • コントローラはUserオブジェクトを作成し、それをUserDAOに渡してデータベースに保存します

  • コントローラはUserオブジェクトを作成し、そのコンストラクタでuserオブジェクトは自分自身をデータベースに保存するためにuserDAOを呼び出します。

  • これはコードの臭いであり、コントローラーがユーザーの作成を要求する追加のクラス「UserManager」がありません。UserManagerは、ユーザーを作成し、UserDAOに保存するように依頼する責任があります。

コントローラが担当するのはリクエストを正しいモデルオブジェクトに委任することだけなので、3番目のオプションが最適だと本当に感じています。あなたの好きな方法は何ですか?私はここで何かが欠けていますか?

4

5 に答える 5

19

私のDAOの経験から、最初のアプローチが唯一の正しいアプローチです。その理由は、責任が最も明確で、混乱が最も少ないためです(非常に立派なプログラマーの中には、DAO自体を混乱と見なしている人もいます。AdamBienは、DAOにすでに実装されている元のDAOパターンと、それ以降のDAOEntityManagerはほとんど不要な「パイプ」であると考えています)。

アプローチ2は、モデルをDAOにバインドし、「上流の依存関係」を作成します。私が言いたいのは、通常、モデルは別々のパッケージとして配布されており、それらの永続性の詳細を知らない(そしてそうあるべきである)ということです。あなたが説明しているものと同様のパターンは、アクティブレコードパターンです。これはRubyonRailsで広く使用されていますが、Javaでは同等のエレガンスとシンプルさで実装されていません。

アプローチ3-ポイントは何であると思われますUserManagerか?この例では、マネージャーは2つのタスクを実行します。マネージャーはユーザーファクトリの役割を果たし、永続化要求のプロキシです。工場であり、必要な場合は、UserFactory追加のタスクを課すことなく名前を付ける必要があります。プロキシに関しては、なぜ必要なのですか?

私見という名前のほとんどのクラス...Managerには匂いがあります。名前自体は、クラスに明確な目的がないことを示しています。クラスに名前を付けたいという衝動があるときはいつでも...Manager、より適切な名前を見つけたり、自分のアーキテクチャについて真剣に考えたりするための合図です。

于 2012-07-27T13:30:14.497 に答える
1

最初のアプローチの場合。私見、DAOオブジェクトでメソッドを呼び出すコントローラーは適切な設計ではありません。コントローラーは、ビジネスに関する「サービス」レベルのオブジェクトを要求する必要があります。これらの「サービス」がデータを保持する方法は、コントローラーにとって問題ではありません。

2 番目のアプローチの場合。オブジェクトを作成したいだけの場合もあるため、コンストラクターの義務と永続的な義務をこのように密結合してはなりません。

最後に、マネージャーまたはサービス オブジェクトは、レイヤード アーキテクチャの優れた抽象化です。このようにして、ビジネス フローを適切なクラスとメソッドにグループ化できます。

しかし Play では、ケース クラスのコンパニオン オブジェクトも DAO として使用するのに適しています。これらのオブジェクトのシングルトンの性質により、良い候補になります。

case class TicketResponse(appId: String, ticket: String, ts: String)

object TicketResponse{
  implicit val ticketWrites = Json.writes[TicketResponse]

  def save(response: TicketResponse) = {

    val result = DB.withConnection {
      implicit connection =>

        SQL("insert into tickets(ticket, appid, ts)"
          +   " values ({ticket},{appid},{ts})")
          .on('ticket -> response.ticket, 'appid -> response.appId, 'ts -> response.ts).executeInsert()
    }

  }

}
于 2014-07-31T13:06:46.257 に答える
0

データアクセスオブジェクト(DAO)は、アプリケーションのデータアクセス層の近くで使用する必要があります。データアクセスオブジェクトは、実際にデータアクセスアクティビティを実行します。したがって、これはデータアクセス層の一部です。

DAOの前のアーキテクチャ層は、プロジェクトによって異なる可能性があります。

コントローラは基本的にリクエストフローを制御するためのものです。つまり、UIに近いものです。マネージャー、ハンドラーは悪い考えですが、コントローラーとDAOの間にレイヤーを追加することはできます。そのため、コントローラーはリクエストから送信されるデータまたは送信されるデータを前処理します(データの健全性、セキュリティ、ローカリゼーション、i18n、JSONへの変換など)。ドメインオブジェクト(この場合はユーザー)の形式でデータをサービスに送信します。このサービスは、このユーザーに対していくつかのビジネスロジックを呼び出すか、いくつかのビジネスロジックに使用します。そして、それをDAOに渡します。

JSP、Webサービス、ハンドヘルドデバイスなどの複数のクライアントをサポートしている場合、コントローラーレイヤーにビジネスロジックを配置することは適切ではありません。

于 2012-07-27T14:34:38.160 に答える
0

Controller がMVCの「C」を意味すると仮定すると、3番目のオプションが正しいアプローチです。一般的に言えば、Controller コードはフレームワークの規則を拡張または従います。MVC の理想の 1 つはフレームワークを交換することです。これは実際にはコントローラーであり、比較的簡単なはずです。コントローラーは、モデル レイヤーとビュー レイヤーの間でデータをやり取りするだけです。

モデルの観点から、コントローラーはドメイン モデルの前に位置するサービス レイヤー(コンテキスト境界) と対話する必要があります。このオブジェクトは、サービス層の一部と見なす部品の例です。これは、ドメイン モデルのパブリック API です。UserManager

于 2012-07-27T14:46:39.037 に答える
-2

典型的なWebアプリケーションの場合、私はPlayのJPAとデータベース実装を備えたPlayフレームワークを好みます。それははるかに生産的な方法です。

こちらhttp://www.playframework.org/documentation/1.2.5/jpa とこちら http://www.playframework.org/documentation/1.2.5/guide1http://www.playframeworkをご覧ください。 org / documentation / 1.2.5 / guide2

それでおしまい))

于 2012-07-27T13:29:53.977 に答える