2012-07-27 9 views
11

私はDAOパターンに関する多くの情報を検索しましたが、その点が分かります。しかし、私はほとんどの説明が全体の話を伝えていないように感じる、そして、それはあなたが実際にあなたのDAOをどこで使うのかということを意味する。だから私は正しい方法でUserクラスと私のためのユーザーを保存し、復元することができます対応UserDAO、持っている場合例えば:DAOパターンとモデルオブジェクト

  • をコントローラには、ユーザーオブジェクトを作成し、にUserDAOに渡しデータベース

  • コントローラに保存することは、ユーザーオブジェクトを作成し、そのコンストラクタでユーザーオブジェクトは、これはコードのにおいで、あなたが

  • データベースに自分自身を救うためにuserDAOを呼び出しますコントローラーがユーザーの作成を要求する余分なクラス「UserManager」がありません。コントローラが担当することがすべて正しいモデルオブジェクトへの要求を委任されているためUserManagerが、ユーザーを作成し、それを

第三の選択肢が最善であるように私は本当に感じを保存するためにUserDAOを尋ねるために責任があります。 お気に入りの方法は何ですか?私はここに何かを逃していますか

答えて

12

のDAOとの私の経験から、最初のアプローチは、唯一の正しいものです。その理由は、それが最も明確な責任を持ち、最も混乱しないプログラマーであることです(まあ、DAOそのものが混乱していると考えているプログラマーもいる).Adam BienはすでにEntityManagerに実装されている元のDAOパターンと、

アプローチ2はモデルをDAOにバインドし、 "上流依存性"を作成します。私の言うことは、通常、モデルは別々のパッケージとして配布されており、永続性の詳細を知らないことです。あなたが記述しているものと同様のパターンがActive Record patternです。これはRuby on Railsで広く使用されていますが、Javaでは同等の優雅さとシンプルさで実装されていません。

アプローチ3 - UserManagerのポイントは何ですか?あなたの例では、Managerは2つのタスクを実行します。これはUserファクトリの任務を持ち、永続性要求のプロキシです。ファクトリで必要なものがある場合は、追加のタスクを課さずにUserFactoryという名前を付ける必要があります。代理人について - なぜあなたはそれを必要とすべきですか?

IMHOほとんどのクラス...Managerには匂いがあります。名前自体には、そのクラスに明確な目的がないことが示唆されています。私がクラス...Managerの名前を付けるような衝動があるときはいつでも、私はより良い名前を見つけたり、自分のアーキテクチャについて懸命に考えることができます。

+1

これを追加するだけです。私は通常、セッション/トランザクションの管理を担当するUserServicesオブジェクトも作成します。私はその後、実際にUserServicesから呼び出されたクエリを実行する責任があるUserDAOを持っています。 – sbrattla

+0

@sbrattla - ユーザートランザクションを使用している場合、これは間違いなく理にかなっています。 OPはそれに言及しなかったが、私は自動的にEJBトランザクションを想定していた。 Kneejerk :) – kostja

+0

あなたが同意しない場合は@Tom - 詳細を教えてください – kostja

0

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

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

コントローラは基本的に要求フローを制御します。だから彼らはUIのような親切なものです。 マネージャ、ハンドラは悪い考えですが、コントローラとDAOの間にレイヤーを追加することはできます。したがって、コントローラは、リクエストや外出(データの健全性、セキュリティ、ローカリゼーション、i18n、JSONへの変換など)から来ているデータを前処理します。これは、ドメインオブジェクト(この場合User)の形でサービスにデータを送信します。サービスはこのユーザーのビジネスロジックを呼び出すか、ビジネスロジックの一部として使用します。そしてそれはそれをDAOに渡すでしょう。コントローラ層のビジネス・ロジックを使用して、などのJSP、Webサービス、ハンドヘルド機器、などの複数のクライアントをサポートしている場合はコントローラを想定し

0

MVCの「C」を意味し、あなたの第三の選択肢が正しいと良いではありません持っ

アプローチ。一般にコントローラコードは、フレームワークの規約を継承するか、または継承します。 MVCの理想の一つは、実際にコントローラであるスワッピングフレームワークが比較的簡単にできることです。コントローラは、モデルレイヤーとビューレイヤーの間でデータを前後に移動する必要があります。

モデルの観点から、コントローラはdomain modelの前に座ってservice layer - a contextual boundary - と対話する必要があります。 UserManagerオブジェクトは、サービスレイヤの一部と見なされる部分の例です。つまり、ドメインモデルのパブリックAPIです。

0

最初のアプローチでは、 IMHO、コントローラが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() 
    } 

    } 

} 
関連する問題