简体   繁体   English

在Scala中DAO模式是否已过时?

[英]Is DAO pattern obsolete in Scala?

Let's consider a simple example of DAO pattern. 我们来看一个DAO模式的简单例子。 Let Person is a value object and PersonDAO is the correspondent trait, which provides methods to store/retrieve Person to/from the database. Person是一个值对象, PersonDAO是对应的特征,它提供了在数据库中存储/检索Person方法。

trait PersonDAO {
  def create(p:Person)
  def find(id:Int)
  def update(p:Person)
  def delete(id:Int)
}

We use this pattern (as opposed to Active Record , for example), if we want to separate the business domain and persistence logic. 如果我们想要分离业务域和持久性逻辑,我们使用这种模式(例如,与Active Record相对)。

What if we use another approach instead ? 如果我们使用其他方法呢? We will create PersonDatabaseAdapter 我们将创建PersonDatabaseAdapter

trait PersonDatabaseAdapter{
  def create
  def retrieve(id:Int)
  def update
  def delete
}

and implicit conversion from Person to it. Person到它的隐式转换

implicit def toDatabaseAdapter(person:Person) = new PersonDatabaseAdapter {
  def create =  ...
  def retrieve(id:Int) = ...
  def update = ...
  def delete = ...
}

Now if we import these conversions, we can write client code to manipulate Persons and store/retrieve them to/from the database in the following manner: 现在,如果我们导入这些转换,我们可以编写客户端代码来操作Persons ,并以下列方式将数据存储/检索到数据库:

val person1 = new Person
...
person1.create
...
val person2 = new Person
...
person2.retrieve(id)
...

This code looks like Active Record but the business domain and persistence are still separated. 此代码看起来像Active Record但业务域和持久性仍然是分开的。

Does it make sense ? 是否有意义 ?

Well, I don't know anything about "obsolete" patters. 好吧,我对“过时”的模式一无所知。 Pattern is a pattern and you use it where appropriate. 模式是一种模式,您可以在适当的地方使用它。 Also, I don't know if any pattern should be obsolete in a language unless language itself implements it with the same functionality. 此外,我不知道语言是否应该在语言中过时,除非语言本身使用相同的功能实现它。

Data access object is not obsolete to my knowledge: 据我所知,数据访问对象并不过时:

http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

http://en.wikipedia.org/wiki/Data_access_object http://en.wikipedia.org/wiki/Data_access_object

It seems to me that you are still using the DAO pattern. 在我看来,你仍在使用DAO模式。 You have just implemented it differently. 您刚刚以不同方式实现了它。

I actually found this question because I was researching whether the DAO pattern is dead in plain ol' Java, given the power of Hibernate. 我实际上发现了这个问题,因为考虑到Hibernate的强大功能,我正在研究DAO模式是否在普通的Java中死了。 It seems like the Hibernate Session is a generic implementation of a DAO, defining operations such as create, save, saveOrUpdate, and more. 看起来Hibernate Session是DAO的通用实现,定义了诸如create,save,saveOrUpdate等操作。

In practice, I have seen little value in using the DAO pattern. 在实践中,我发现使用DAO模式没什么价值。 When using Hibernate, the DAO interfaces and implementations are redundant wrappers around one-liner Hibernate Session idioms, eg, getSession().update(...); 当使用Hibernate时,DAO接口和实现是围绕单行Hibernate Session习语的冗余包装器,例如getSession()。update(...);

What you end up with is duplicate interfaces - a Service interface that redefines all of the methods in the DAO interface plus a few others implemented in terms of those. 您最终得到的是重复接口 - 一个服务接口,它重新定义了DAO接口中的所有方法以及根据这些接口实现的其他几个方法。

It seems that Spring + Hibernate has reduced persistence logic almost to a triviality. 似乎Spring + Hibernate几乎将持久性逻辑降低到了微不足道的程度。 Persistence technology portability is NOT needed in almost all applications. 几乎所有应用程序都不需要持久性技术可移植性。 Hibernate already gives you database portability. Hibernate已经为您提供了数据库可移植性。 Sure, DAOs would give you the ability to change from Hibernate to Toplink, but in practice, one would never do this. 当然,DAO会让你有能力从Hibernate变为Toplink,但在实践中,人们永远不会这样做。 Persistence technologies are already leaky abstractions and applications are built to deal with this fact - such as loading a proxy for setting associations vs. performing a database hit - which necessarily couples them to the persistence technology. 持久性技术已经是漏洞抽象,应用程序是为了处理这一事实而构建的 - 例如加载用于设置关联的代理与执行数据库命中 - 这必然将它们与持久性技术相结合。 Being coupled to Hibernate is not really so bad though since it does its best to get out of the way (no checked exceptions a la JDBC and other nonsense). 与Hibernate耦合并不是那么糟糕,因为它尽力避开(没有检查过的例外,JDBC和其他废话)。

In summary, I think that your Scala implementation of the DAO pattern is fine, though you could probably create a completely generic mixin that would give basic CRUD operations to any entity (most competent devs tend to implement a "generic DAO" base class in Java, too). 总之,我认为你的DAO模式的Scala实现很好,尽管你可能创建一个完全通用的mixin,它可以为任何实体提供基本的CRUD操作(大多数有能力的开发人员倾向于在Java中实现“泛型DAO”基类) ,也)。 Is that what Active Record does? 这是Active Record的作用吗?

/end of random comments/ /随机评论结束/

I believe your PersonDatabaseAdapter mutates Person in its retrieve(id: Int) method. 我相信你的PersonDatabaseAdapter在其retrieve(id: Int)方法中改变了Person So this pattern forces your domain objects to be mutable, while the Scala community seems to favor immutability due to the functional nature (or features) of the language. 因此,这种模式会强制您的域对象变得可变,而Scala社区似乎由于语言的功能性(或特性)而倾向于不可变性。

Otherwise, I think the DAO pattern still has the same advantages and disadvantages (listed here ) in Scala as it does in Java. 否则,我认为DAO模式在Scala中仍然具有与在Java中相同的优点和缺点(在列出)。

现在我注意到Repository模式非常受欢迎,特别是因为它的术语使它看起来像你正在处理集合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM