私は、通常は CRUD メソッドで始まる、JDBC ベースの古い DAO コードを数多く見てきました。私の質問は、特に検索方法、または「ファインダー」に関連しています。通常、DAO は次の 2 つの方法で開始されます。
- すべてを見つけて返す
- 一意の識別子に基づいて特定のインスタンスを取得する
多くの場合、これら 2 つのファインダーでは不十分です。私は通常、次のようなファインダ メソッドを追加するために DAO クラスが繰り返し変更されているのを目にすることになります。
- ALL where {condition} を検索して返す
新しい {condition} をサポートする必要がある場合、または既存のメソッドを変更して新しいパラメータをフラグとして追加し、メソッド内の SQL クエリを変更して追加の条件をサポートする場合に、さらにメソッドが追加されます。
これは醜いアプローチであり、Open-Closed Principle に違反しています。新しい検索条件をサポートする必要があるたびに、DAO クラスが継続的に変更されるのを目にするのは、私にとって常に気になることでした。この質問に関する調査は、多くの場合、Repository パターンと、検索の条件を仕様またはクエリ オブジェクトとしてカプセル化し、それらをファインダー メソッドに渡すことを示しています。ただし、これは、データセット全体のメモリ内コレクションがある場合、または何らかの ORM を使用している場合にのみ実行可能と思われます (私は古い JDBC コードを使用しています)。
私は、DAO がメモリ内のコレクションとして管理するデータ セット全体を遅延ロードし、仕様パターンを検索用のクエリとして使用するソリューションを検討しました。次に、creates、updates、または deletes メソッドが呼び出されたときにデータベースを更新する、ある種のオブザーバーをコレクションに実装します。しかし、明らかにパフォーマンスとスケーラビリティが大幅に低下します。
これについて何か考えはありますか?
これまでの回答に感謝します。コマンド/ポリシー パターンを使用してデータ アクセス リクエストをカプセル化することについて、どう思いますか? 個々の具象コマンドは、特定の種類のアクセスを表すことができ、Invoker に渡すことができます。最終的に多数の具象コマンド クラスが作成されることになりますが、各クラスは 1 種類のアクセスのみに焦点を当てており、非常にテスト可能で分離されている必要があります。
public abstract class Command<R>{
public <R> execute();
public void setArguments(CommandArguments args){
//store arguments
}
}
//map based structure for storing and returning arguments
public class CommandArguments{
public String getAsString(String key);
public String getAsInt(String key);
//... others
}
//In some business class...
Command command = CommandFactory.create("SearchByName");
CommandArguments args = new CommandArguments();
args.setValue("name", name);
// others
command.setArguments(args);
List<Customer> list = command.execute();