Spring / Hibernate/jspの標準スタックと一般的なレイヤーを使用するJavaEEアプリケーションがあります。
- @Repository(またはDAO)
- @サービス
- @コントローラ
各リポジトリには、いくつかのfind ...メソッドがあります(たとえば、BookRepositoryの場合:単純なfindById、findByTitle、findByAuthor、より複雑なfindMostUsed、findMostCommentedなど)。
サービス層には、リポジトリを呼び出すビジネスロジックが含まれています。
コントローラはサービスメソッドを呼び出し、JSPで使用されるModelAndViewにデータを入力します。
もちろん、サービスには複雑なビジネスロジックを持つメソッドがあります。しかし、次のような愚かな方法がたくさんあるのは面倒です。
public List<Book> findMostUsed() {
return repository.findMostUsed();
}
public List<Book> findMostCommented (boolean includeRating) {
return repository.findMostCommented(includeRating);
}
...
したがって、これらは単なる委任です(これらの検索メソッドにはビジネスロジックはありません。リポジトリ内のDBクエリがすべての選択とグループ化を行います)。
リポジトリ内のメソッドを変更する必要がある場合は、サービスも変更する必要があります。2年間の開発の後、これらのメソッドにロジックを追加する必要はありませんでした。クエリとそのパラメータのみが変更されました。
人々がコントローラー->ファサード->サービス->リポジトリ->DAOを作成し、すべてのレイヤーがこのようなメソッドで溢れているという、さらに悪いデザインを見ました。
より良いデザインは何でしょうか?
たぶん、これらすべてのメソッドを削除し、サービスをより汎用的なものに変換します(単一のBookService(単一責任の原則に違反する)ではなく、BookPricingService、BookRatingServiceなど)。次に、コントローラーはサービスレイヤーとリポジトリレイヤーの両方を呼び出しますが、これは適切ではありません。
たぶん、findByCriteria(criteria)などのfindメソッドをより一般的にして、その数を減らします。ただし、問題はクエリが非常に異なることであり、これは、基準タイプに基づいて正しいクエリ/パラメータを選択する一種のswitch-caseブロックで終了します。ところで、Spring-Dataは、@Queryアノテーションを使用してクエリごとに1つのメソッドも推奨しています。
たぶん、これは抽象化レイヤーを持つために支払うべき価格ですか?