【发布时间】:2011-12-25 00:49:52
【问题描述】:
我一直在复习我的设计模式,并想到我无法在任何地方找到一个好的答案。所以也许有更多经验的人可以帮助我。
DAO 模式是否仅用于访问数据库中的数据?
我找到的大多数答案都是肯定的;事实上,大多数关于 DAO 模式的讨论或写作都倾向于自动假设您正在使用某种数据库。
我不同意。我可以有如下的 DAO:
public interface CountryData {
public List<Country> getByCriteria(Criteria criteria);
}
public final class SQLCountryData implements CountryData {
public List<Country> getByCriteria(Criteria criteria) {
// Get From SQL Database.
}
}
public final class GraphCountryData implements CountryData {
public List<Country> getByCriteria(Criteria criteria) {
// Get From an Injected In-Memory Graph Data Structure.
}
}
在这里,我有一个 DAO 接口和 2 个实现,一个与 SQL 数据库一起使用,一个与内存中的图形数据结构一起使用。它是否正确?或者图形实现是要在其他类型的层中创建的?
如果它是正确的,那么抽象每个 DAO 实现所需的具体实现细节的最佳方法是什么?
例如,以上面引用的 Criteria Class I 为例。假设是这样的:
public final class Criteria {
private String countryName;
public String getCountryName() {
return this.countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
}
对于 SQLCountryData,它需要以某种方式将 countryName 属性映射到 SQL 标识符,以便生成正确的 SQL。对于 GraphCountryData,可能需要创建某种针对 countryName 属性的谓词对象,以从图中过滤掉失败的顶点。
在不将针对抽象 CountryData 的客户端代码与此类实现特定细节耦合的情况下,抽象此类细节的最佳方法是什么?
有什么想法吗?
编辑:
我包含的 Criteria 类的示例很简单,但考虑一下我是否要允许客户端构造复杂的条件,它们不仅应该指定要过滤的属性,还应该指定相等运算符、逻辑运算符复合标准和价值。
【问题讨论】:
-
一方面,我不要将 DAO 仅用于数据库访问。在我的设计中,我经常有一个从某个来源读取数据的 DAO,就像名字所说的那样。有时,它是一个数据库,有时它可能是一个文件、一个特定的流、一个加密设备、硬件随机数生成器,等等。只要它为我提供数据,而且我不在乎数据来自哪里,我很乐意遵循 DAO 模式。这也使得以后重构代码变得容易,原来的 SQL 数据库可能会变成其他一些存储机制,除了 DAO 实现之外,对我的应用程序没有任何影响。
标签: java design-patterns dao