我一直在研究我的设计模式,并想到我无法在任何地方找到一个好的答案。所以也许有经验的人可以帮助我。
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属性的某种Predicate对象,以从失败的图形中过滤出顶点。
如果没有将客户端代码与抽象的CountryData相结合,并使用类似这样的实现特定细节,那么抽象这样的细节的最佳方法是什么?
有什么想法?
编辑:
我在Criteria Class中包含的示例很简单,但考虑是否要允许客户端构造复杂的标准,它们不仅要指定要过滤的属性,还要指定相等运算符,逻辑运算符为复合标准和价值。
答案 0 :(得分:4)
DAO是DAL(数据访问层)的一部分,您可以使用任何类型的实现(XML,RDBMS等)支持数据。您只需确保在运行时注入/使用项目实例。像Spring / Guice这样的DI框架在这种情况下大放异彩。此外,您的Criteria
接口/实现应该足够通用,以便仅捕获业务详细信息(即国家/地区名称标准),实际映射将再次由实现类处理。
对于SQL,在您的情况下,您可以手动生成SQL,使用像Spring这样的帮助程序库生成SQL,或者使用像MyBatis这样的完整框架。在我们的项目中,Spring XML配置文件用于解耦客户端和实现;它可能会因你的情况而有所不同。
编辑:我发现您在上一个问题中提出了类似的问题。答案仍然是一样的。您可以在界面中添加所需的灵活性;你只需要确保实现足够聪明,以理解它收到的所有参数,并将它们适当地映射到底层源。在我们的例子中,我们从业务层检索了值对象,并将其转换为SQL实现层中可供MyBatis使用的映射。同样,这个过程非常透明,服务层与DAO通信的唯一方法是通过接口定义的值对象。
答案 1 :(得分:2)
不,我不相信它只与 数据库绑定。首字母缩略词是Data Access Object
,而不是“数据库访问对象”,因此它可以与任何类型的数据源一起使用。
它的重点是将应用程序与后备数据存储区分开,以便可以随意修改存储,前提是它仍然遵循相同的规则。
这不仅意味着草拟Oracle并投入DB2。它也可能意味着切换到完全不基于DBMS的解决方案。
答案 2 :(得分:2)
从我在实际项目中看到的,是的,你是对的,你应该提供不同的DAO实现来以不同的方式访问数据。 在这种情况下,一个dao转到DB,另一个dao实现转到对象图。
DAO的界面必须非常仔细地设计。您的“标准”必须足够通用,以封装您从中获取数据的方式。 如何实现这种解耦水平?答案可能会因您的系统而异,一般来说,我会说,答案是“像往常一样,通过添加另一个级别的间接”:)
您还可以将您的条件对象视为一个数据对象,其中您只提供查询所需的数据。在这种情况下,您甚至不需要支持不同的Criteria。 DAO的每个特定实现都将采用这些数据并以自己不同的方式对待它:一个将构建图形查询,另一个将它绑定到您的SQL。
为了尽量减少对维护的麻烦,我建议您使用依赖管理框架(例如Spring)。通常这些框架非常适合实例化DAO对象并且可以很好地协同工作。 祝你好运!
答案 3 :(得分:0)
不,DAO仅适用于数据库是一种常见的误解。
DAO是“数据访问对象”,而不是“数据库访问对象”。因此,无论您需要将数据传入/传出(例如文件,内存,数据库等),都可以使用DAO。
在Domain Driven Design中有一个Repository模式。虽然Repository
作为一个单词远比三个随机字母(DAO)好,但概念是相同的。
DAO / Repository模式的目的是抽象一个后备数据存储,它可以是任何可以保存状态的数据。