java DAO 模式和模型对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11688683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DAO pattern and model objects
提问by Tom
I have looked up a lot of information about the DAO pattern and I get the point of it. But I feel like most explainations aren't telling the whole story and by that I mean where would you actually use your DAO. So for example if I have a User class and a corresponding UserDAO that is able to save and restore users for me, which is the correct way:
我查了很多关于 DAO 模式的信息,我明白了。但我觉得大多数解释并没有说明整个故事,我的意思是你实际上会在哪里使用你的 DAO。例如,如果我有一个 User 类和一个相应的 UserDAO 可以为我保存和恢复用户,这是正确的方法:
The controller creates the User object and passes it to the UserDAO to save it to the database
The controller creates the User object and in its constructor the user object makes a call to the userDAO in order to save itself into the database
This is a code smell and you are missing an extra class "UserManager" which the controller will ask to create the user. The UserManager is responsible for creating the user and asking the UserDAO to save it
控制器创建 User 对象并将其传递给 UserDAO 以将其保存到数据库
控制器创建 User 对象,并且在其构造函数中,用户对象调用 userDAO 以将自身保存到数据库中
这是一种代码异味,您缺少一个额外的类“UserManager”,控制器将要求它创建用户。UserManager 负责创建用户并要求 UserDAO 保存它
I really feel like the third option is the best, because all that the controller is responsible for is delegating the request to the correct model object. What is your favorite way? Am I missing something here ?
我真的觉得第三个选项是最好的,因为控制器负责的只是将请求委托给正确的模型对象。你最喜欢的方式是什么?我在这里错过了什么吗?
采纳答案by kostja
From my experience with DAOs, the first approach is the only correct one. The reason is that it has the clearest responsibilities and produces the least clutter (well, some very respectable programmers regard DAOs themselves as clutter. Adam Bien sees the original DAO pattern already implemented in the EntityManager
and further DAOs to be mostly unnecessary "pipes")
根据我对 DAO 的经验,第一种方法是唯一正确的方法。原因是它的职责最明确,产生的混乱最少(好吧,一些非常受人尊敬的程序员认为 DAO 本身就是混乱的。Adam Bien 认为已经在 DAO 中实现的原始 DAO 模式EntityManager
和进一步的 DAO 大多是不必要的“管道”)
Approach 2binds the model to the DAO, creating an "upstream dependency". What I mean is that usually the models are distributed as separate packages and are (and should be) ignorant of the details of their persistence. A similar pattern to what you are describing is the Active Record pattern. It is widely used in Ruby on Rails but has not been implemented with equal elegance and simplicity in Java.
方法 2将模型绑定到 DAO,创建“上游依赖”。我的意思是,模型通常作为单独的包分发,并且(并且应该)不知道它们的持久性细节。与您所描述的类似的模式是Active Record 模式。它在 Ruby on Rails 中被广泛使用,但在 Java 中并没有以同样优雅和简单的方式实现。
Approach 3- what is supposed to be the point of the UserManager
? In your example the Manager performs 2 tasks - it has the duties of a User factory and is a proxy for persistence requests. If it is a factory and you need one, you should name it UserFactory
without imposing additional tasks on it. As for the proxy - why should you need it?
方法 3- 应该是什么UserManager
?在您的示例中,管理器执行 2 个任务 - 它具有用户工厂的职责,并且是持久性请求的代理。如果它是一个工厂并且你需要一个,你应该命名它UserFactory
而不给它施加额外的任务。至于代理——你为什么需要它?
IMHO most classes named ...Manager
have a smell. The name itself suggests that the class has no clear purpose. Whenever I have an urge to name a class ...Manager
, it's a signal for me to find a better fitting name or to think hard about my architecture.
恕我直言,大多数命名的类...Manager
都有气味。这个名字本身表明这个类没有明确的目的。每当我有想命名一个类的冲动时...Manager
,这是一个信号,让我找到一个更合适的名称或认真思考我的架构。
回答by Atul
The Data Access Object (DAO) should be used closer to the data access layer of your application. The data access object actually does the data access activities. So it is part of data access layer.
数据访问对象 (DAO) 应更靠近应用程序的数据访问层使用。数据访问对象实际上执行数据访问活动。所以它是数据访问层的一部分。
The architecture layers before DAO could vary in projects.
DAO 之前的架构层可能因项目而异。
Controllers are basically for controlling the request flow. So they are kind of close to UI. Although, a Manager, Handler is a bad idea, we could still add a layer between controller and DAO. So controller will pre-process the data that is coming from a request or going out (data sanity, security, localization, i18n, transform to JSON, etc). It sends data to service in the form of domain objects (User in this case). The service will invoke some business logic on this user or use it for some business logic. And it would then pass it to DAO.
控制器基本上用于控制请求流。所以它们有点接近 UI。虽然,一个管理器,处理程序是一个坏主意,我们仍然可以在控制器和 DAO 之间添加一个层。因此控制器将预处理来自请求或输出的数据(数据完整性、安全性、本地化、i18n、转换为 JSON 等)。它以域对象(在本例中为用户)的形式向服务发送数据。该服务将调用此用户的某些业务逻辑或将其用于某些业务逻辑。然后它将它传递给 DAO。
Having the business logic in controller layer is not good if you are supporting multiple clients like JSPs, WebServices, handheld devices, etc.
如果您支持多个客户端,如 JSP、Web 服务、手持设备等,那么在控制器层拥有业务逻辑并不好。
回答by orangepips
Assuming Controller means the "C" in MVC, your third option is the right approach. Generally speaking Controller code extends or follows the conventions of a framework. One of the ideals of MVC is swapping frameworks, which is really the Controller, should be relatively easy. Controllers should just move data back and forth between the model and view layers.
假设 Controller 在MVC 中的意思是“C” ,你的第三个选择是正确的方法。一般来说,控制器代码扩展或遵循框架的约定。MVC 的理想之一是交换框架,这实际上是 Controller,应该相对容易。控制器应该只是在模型层和视图层之间来回移动数据。
From a model perspective, Controllers should interact with a service layer- a contextual boundary- in sitting front of the domain model. The UserManager
object would be an example of a piece that you would consider part of your service layer - that is the domain model's public API.
从模型的角度来看,控制器应该与位于域模型前面的服务层(一个上下文边界)进行交互。该对象将是您将其视为服务层的一部分的一个示例 - 即域模型的公共 API。UserManager
回答by LostMohican
For the first approach; IMHO, controller calling a method on a DAO object is not a good design. Controllers must be asking "service" level objects about business. How these "services" persist the data is not a concern for the controller.
对于第一种方法;恕我直言,控制器在 DAO 对象上调用方法不是一个好的设计。控制器必须询问有关业务的“服务”级别对象。这些“服务”如何持久保存数据不是控制器关心的问题。
For the second approach; sometimes you may want to just create the object, so constructor duty and persisting duty must not be tightly coupled like this.
对于第二种方法;有时您可能只想创建对象,因此构造函数职责和持久职责不能像这样紧密耦合。
Lastly, the manager or the service objects is a good abstraction for the layered architecture. This way you can group the business flows in the appropriate classes and methods.
最后,管理器或服务对象是分层架构的一个很好的抽象。通过这种方式,您可以将业务流分组到适当的类和方法中。
But for Play, companion objects of case classes are also a good candidate to use as DAO. The singleton nature of these objects make it a good candidate.
但是对于 Play,case 类的伴生对象也是用作 DAO 的不错选择。这些对象的单例特性使其成为一个很好的候选者。
case class TicketResponse(appId: String, ticket: String, ts: String)
object TicketResponse{
implicit val ticketWrites = Json.writes[TicketResponse]
def save(response: TicketResponse) = {
val result = DB.withConnection {
implicit connection =>
SQL("insert into tickets(ticket, appid, ts)"
+ " values ({ticket},{appid},{ts})")
.on('ticket -> response.ticket, 'appid -> response.appId, 'ts -> response.ts).executeInsert()
}
}
}
回答by Andrey Borisov
for typical webapp i will prefer playframework with play's JPA and database implementation. It much more productive way.
对于典型的 webapp,我更喜欢带有 play 的 JPA 和数据库实现的play框架。它更有成效的方式。
please take a look here http://www.playframework.org/documentation/1.2.5/jpaand here http://www.playframework.org/documentation/1.2.5/guide1and http://www.playframework.org/documentation/1.2.5/guide2
请看这里http://www.playframework.org/documentation/1.2.5/jpa和这里 http://www.playframework.org/documentation/1.2.5/guide1和 http://www.playframework。 org/documentation/1.2.5/guide2
That's it))
而已))