web-dev-qa-db-ja.com

サービス層とコントローラー:誰が何をするのか?

クラスでは、Springアプリケーションを構築する方法を学習しています。Springは直接関与していませんが、DAOおよびサービスレイヤーオブジェクトのインターフェイスを作成する方法を学習しています。

私が間違っている場合は修正してください:DAOレイヤーはかなり抽象的です。これはCRUD操作を含み、さらにデータの読み取りに使用されます(つまり、すべてのオブジェクトの取得、特定のオブジェクトの取得など)。

サービス層:ものを作成したり削除したりするためのサービスが含まれます。これがビジネスロジックの場所です。

これで、これらすべてがサービス層で理にかなっています。 「更新」オブジェクトを除く。オブジェクトをデータベースに保存するだけの「更新」関数を配置するだけですか?または、そこにもロジックを定義する必要がありますか?これが私の混乱ですが、私の理解では、Springのオブジェクトは単なるPOJOです。では、誰がデータを検証するのでしょうか。

オブジェクトに「子」があるとしましょう:NameSurNameGenderPhotoBirthdateフィールド。サービスに名前を付けるにはどうすればよいですか?または、コントローラーに検証を任せることもできますが、これは私には適切ではないようです。一方、サービスレイヤーに呼び出す必要があるすべてのセッターを委任することも適切ではないようです。

つまり、基本的には、サービスレイヤー経由でオブジェクトを保存する方法を教えてください。

47
toomuchcs

コントローラーがChildオブジェクトへの変更を永続化できるようにしたい場合、従来は、サービスにChildService.update(Child newchild)のような名前のメソッドがあり、正しいDAOの呼び出しを処理しますこの子の新しいバージョンを永続化します。

コントローラーは自由に子にサービスを要求し、(おそらくユーザー入力に基づいて)周りのフィールドを変更します-適切な設計では、コントローラーは子POJOで何らかの作業を行い、サービスに変更を永続化するように要求します。モデルPOJOは、コントローラー、サービス、またはDAOについて何も認識していないはずですが、提案どおりにデータを保持するだけです-setName()またはsetGender()へのすべての呼び出しが自動的に行われることは望ましくありませんデータベースの更新。

代わりに、コントローラーまたはサービス、あるいはその両方がChildオブジェクトを取得し、その作業単位内のオブジェクトに対して必要なすべての作業を実行してから、サービス(およびDAO)に変更を永続化するように要求します。

検証は複数のレイヤーで行われる可能性があります-コントローラーはWebユーザーからの入力を検証し、サービスは永続化する前に有効なChildオブジェクトがあることを検証する必要があります。 RESTインターフェース、異なるフロントエンドなどを公開するなど)他のキャパシティでこのサービスを再利用したい場合に備えて、両方のレイヤーである程度の検証を行うことは特に意味があります。 。

29
matt b

通常、Springサービスはトランザクション対応です。同じトランザクションでグループ化する必要があるため、物事は特定のサービスメソッドに入ります。データベースからオブジェクトを取得し、それをいじって、新しいバージョンを保存する場合は、取得と保存を同じサービスメソッドで行う必要があります。したがって、サービスメソッドは、アプリケーションがユーザーのために何をする必要があるかに従って決定されます。

私は、コントローラーをhttpパラメーターの検証に関連する作業に制限し、どのパラメーターでどのサービスメソッドを呼び出すか、httpsessionまたはリクエストに何を入れるか、どのビューにリダイレクトまたは転送するか、または同様のWeb関連のものを決定します。

検証に関する限り:コントローラーで入力パラメーターを検証することは、偽の入力でアプリケーションを壊すことができないことを確認するために良いことです。コントローラでの検証は、入力が構文的に適切であることを確認すること(インジェクション攻撃の検出を含む)になりがちですが、サービスレベルの検証は、データベース内の状態が想定どおりであることを確認することです。

したがって、コントローラーにはWebフレームワークインフラストラクチャコードが含まれ、サービスにはアプリケーションロジックコードが含まれます。

45
Nathan Hughes