我已经看到并使用过很多旧的、基于 JDBC 的 DAO 代码,这些代码通常从 CRUD 方法开始。我的问题特别与检索方法或“发现者”有关。通常,我发现 DAO 以两种方法开始:
- 查找并返回所有
- 根据唯一标识符检索特定实例
通常,这两个发现者是不够的。我通常最终会看到一个 DAO 类被反复修改以添加 finder 方法,如下所示:
- 查找并返回 ALL where {condition}
发生的情况是,当需要支持新的 {conditions} 或修改现有方法以添加新参数作为标志以修改方法内部的 SQL 查询以支持附加条件时,会添加更多方法。
这是一种丑陋的方法,违反了开闭原则。每当需要支持一些新的检索条件时,看到 DAO 类不断修改,这一直是我的烦恼。对这个问题的研究经常将我指向存储库模式并将检索条件封装为规范或查询对象,然后将它们传递给查找器方法。但这似乎只有在您拥有整个数据集的内存集合或使用某种 ORM 时才可行(我正在使用较旧的 JDBC 代码)
我考虑过一种解决方案,该解决方案将 DAO 管理的整个数据集作为内存中的集合延迟加载,然后使用规范模式作为检索查询。然后我在集合上实现某种观察者,它在调用创建、更新或删除方法时只更新数据库。但显然性能和可扩展性会受到严重影响。
对此有什么想法吗?
感谢您到目前为止的回复。我确实有一个想法——您对使用命令/策略模式来封装数据访问请求有何看法?每个单独的具体命令可以代表一种特定类型的访问,并且可以传递给调用者。我最终会得到许多具体命令类,但每个类都将只关注一种访问,并且应该非常可测试和隔离。
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();