JSFのMVC環境での私のアプローチが最善の方法であるかどうかはわかりません。 JSFを最大限に活用しようとしているので、サービスレイヤー(またはMVC用語で言えばモデル)を「設計」する方法を知りたいと思います。
View-Controllerの比率は1対1でなければならないことを私は知っています(例外は除外されています)。では、サービスレイヤーをどのように設計する必要がありますか? 1つの大きなサービスを使用する必要がありますか(そうは思わないでください)?そうでない場合は、サービスを何に分割する必要がありますか?
私のサービスはBeans(MVC用語ではコントローラー)から呼び出され、サービス自体は必要に応じてJPAを使用してDAOを呼び出すことに注意してください。
前もって感謝します
サービス層(ビジネスモデル)は、メインエンティティ(データモデル)を中心に設計する必要があります。例えば。 UserService
for User
、ProductService
for Product
、OrderService
for Order
など。絶対に持ってはいけません。巨大なサービスクラスかそこら。これは非常に緊密な結合です。
サービスレイヤーAPI自体に関しては、Java EE6はサービスレイヤーAPIとしてEJB3.1を提供します。EJB2.0の開発がひどい昔の暗いJ2EE時代では、Springがより頻繁に使用されていました。サービスレイヤーAPIとして使用されています。現在でも使用されているものもありますが、Java EE 6にはSpringから学んだすべてのニースのレッスンが組み込まれているため、 不要 になりました。注そのEJB(およびJPA)は、Tomcatなどのベアボーンservletcontainerでは使用できません。たとえばOpenEJBをその上にインストールする(またはTomEEにアップグレードする)必要があります。
サービスレイヤーAPIの選択に関係なく、ビジネスジョブを完全にサービスレイヤーで実行することにより、JSFバッキングBean(アクション)リスナーメソッドを可能な限り滑らかに保つのが最善です。サービス層はそれ自体notにJSF依存関係を持たないようにする必要があることに注意してください。したがって、サービスレイヤーコードにjavax.faces.*
を(間接的に)直接インポートすると、設計が不適切であることを示します。特定のコード行をバッキングBeanに保持する必要があります(通常、サービス呼び出しの結果に応じてfacesメッセージを追加するコードです)。このようにして、サービス層はJAX-RSやプレーンサーブレットなどの他のフロントエンドで再利用できます。
Java EEアプリケーションのサービスレイヤーの主な利点はコンテナー管理トランザクションの可用性です。@Stateless
EJBでの1つのサービスメソッド呼び出しは事実上単一としてカウントされることを理解する必要があります。 DBトランザクション。したがって、サービスメソッド呼び出しによって呼び出される@PersistenceContext EntityManager
を使用するDAO操作のいずれかで例外が発生すると、completeロールバックがトリガーされます。これはたとえば、最初のDB操作クエリは成功したが、2番目は成功しなかったため、ダーティDB状態ではなくクリーンDB状態になります。
アプリにエンティティがほとんどない場合、サービスとモデルエンティティの1:1の比率は悪くないかもしれません。しかし、それが大きなアプリである場合、サービスが多すぎるでしょう。
サービスの数は、設計しているアプリのユースケースによって異なります。分析フェーズでそれらを特定したら、機能に応じていくつかのグループにグループ化する必要があります。ユースケースの各グループはサービスになり、各ユースケースはそのサービスのメソッドになります。各サービスは複数のモデルエンティティを管理できます(その機能を実行するために必要なDAOをサービスに挿入する必要があります)。通常、サービスのユースケースは、モデルのクラス図で相互に実現されたモデルエンティティを管理します。サービスは、「最大凝集/最小結合」のグッドプラクティスに従う場合があります。
DAOとモデルエンティティの比率は1:1です。各DAOは、そのエンティティのCRUD操作とクエリを実行します。メソッドが2つの関連エンティティをクエリする必要がある場合は、ビジネスコンセプトに応じて、より適切なDAOにメソッドを配置します。
JSFプレゼンテーション層では、ページとコントローラーの比率が1:1ではないため、コントローラーが多すぎます。各サービスのユースケースを実行するために必要なすべてのページを1つのコントローラーにグループ化します。したがって、1:1の比率はコントローラーとサービスの間であり、ページがユースケースを実行するコントローラーに各サービスを注入します。
もちろん、これらは一般的な原則です。あなたはそれらを壊したアプリのいくつかの特定のケースがあるかもしれませんが、それらは少数です。
サービスとコントローラーが多すぎることはないかもしれませんが、ロジックとフィールドが多すぎるため、少なすぎることもありません。妥協する必要があります。