1

Java EE仕様を使用してかなり単純なWebアプリケーションを作成しているとしましょう(これは可能だと聞いています)。このアプリでは、約 10 個のドメイン/データ オブジェクトしかなく、これらは JPA エンティティによって表されます。アーキテクチャ的には、JPA API が DAO の役割を果たすと考えています。もちろん、EntityManager を UI (JSF) で直接使用したくはありません。また、トランザクションを管理する必要があるため、これらのタスクをいわゆるサービス レイヤーに委任します。

より具体的には、汎用メソッドを使用して単一の DataService クラス (CrudService とも呼ばれます) でこれらのタスクを処理できるようにしたいと考えています。インターフェイスの例については、Adam Bien によるこの記事を参照してください: http://www.adam-bien.com/roller/abien/entry/generic_crud_service_aka_dao

私のプロジェクトは、EJB を使用できないという点でその記事とは異なります。そのため、私のサービス クラスは基本的に名前付き Bean であり、トランザクションを手動で処理します。とにかく、データ型ごとに異なるクラスを使用すると、多くの重複したコードや不要なコードが発生するため、データ オブジェクトに対する単純な CRUD 操作のための単一のインターフェイスが必要です。

理想的には、私のビューは次のような方法を使用できます

public <T> List<T> findAll(Class<T> type) { ... }

データを取得します。JSF を使用すると、次のようになります。

<h:dataTable value="#{dataService.findAll(data.class)}" var="d">
  ...
</h:dataTable>

同様に、フォームを検証した後、コントローラーは次のような方法でデータを送信できます。

public <T> void add(T entity) { ... }

確かに、実際には呼び出し元に役立つものを返したいと思うでしょう。

いずれにせよ、この方法でデータを同種のものとして扱うことができれば、これはうまく機能します。残念ながら、特定のオブジェクトを JPA に渡す前に追加の処理を実行する必要がある場合は、機能しなくなります。

たとえば、多対多の関係にある Books と Authors を扱っているとします。各 Book には、その著者を参照する一連の ID があり、各 Author には、その書籍を参照する一連の ID があります。通常、JPA はこの種の関係を管理できますが、場合によっては管理できません (たとえば、Google アプリ エンジンの JPA プロバイダーはこれをサポートしていません)。したがって、たとえば新しい本を永続化する場合、対応する著者エンティティを更新する必要がある場合があります。

私の質問は、これを処理するエレガントな方法があるかどうか、またはデザイン全体の正気を再考する必要があるかどうかです。これに対処するためのいくつかの方法を次に示します。

  1. instanceof 演算子。これを使用して、特別な処理が必要なときに特定のクラスをターゲットにすることができます。おそらく保守性が損なわれ、美しいコードではありませんが、ドメイン オブジェクトが 10 個程度しかない場合は、それほど悪くはありません。

  2. エンティティ タイプごとに異なるサービスを作成します (つまり、BookService と AuthorService)。すべてのサービスは、一般的な DataService 基本クラスから継承し、特別な処理が必要な場合はメソッドをオーバーライドします。この時点で、代わりに DAO と呼ぶこともできます。

いつものように、私は助けに感謝します. 多くの細かい詳細を省略したので、明確化が必要な場合はお知らせください。

4

1 に答える 1

0

サービス層は主に、トランザクションの必要性と、すべてのユースケースに固有のビジネス ロジックの必要性によって正当化されます。一般的なものにすることはあまり意味がありません、IMHO。また、エンティティごとにサービスを用意することもあまり意味がありませんが、それでも私見です。一部のエンティティは密接にリンクされており、サービスによって個別に作成または更新することはできません。また、ほとんどのサービスには複数のエンティティが関与しています。

サービス層は、その名前が示すように、上の層 (プレゼンテーション層) にサービスを提供するために存在します。そのため、アプリケーションが実行する必要のある現実から切り離された汎用インターフェイスを持たないでください。UI レイヤーが必要とするサービスを提供する必要があります。エンティティではなく、ユースケースまたは関連するユースケースのグループに基づいてサービスを分割する方がはるかに論理的だと思います。また、一般的なサービスを設計してから UI レイヤーの実装を開始し、一般的に見られるトラップの 1 つに陥るよりも、UI レイヤーの実装を開始し、必要なサービスを確認してそれらのサービスを実装する方がより論理的だと思います。

  • 非常に多くのサービスがまったく役に立たず、実装されているが使用されていない
  • UIレイヤーは、ボタンがクリックされるたびにN個の低レベルサービスの呼び出しを開始し、トランザクションの整合性を忘れ、サービスレイヤーにあるはずのロジックを含みます.
于 2012-06-27T07:36:33.093 に答える