Tom
Tom

Reputation: 613

DAO pattern and model objects

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:

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 ?

Upvotes: 20

Views: 16683

Answers (5)

LostMohican
LostMohican

Reputation: 3144

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.

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.

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()
    }

  }

}

Upvotes: 1

kostja
kostja

Reputation: 61538

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")

Approach 2 binds 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.

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?

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.

Upvotes: 19

orangepips
orangepips

Reputation: 9971

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.

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.

Upvotes: 0

Atul
Atul

Reputation: 2711

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.

The architecture layers before DAO could vary in projects.

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.

Having the business logic in controller layer is not good if you are supporting multiple clients like JSPs, WebServices, handheld devices, etc.

Upvotes: 0

Andrey Borisov
Andrey Borisov

Reputation: 3170

for typical webapp i will prefer play framework with play's JPA and database implementation. It much more productive way.

please take a look here http://www.playframework.org/documentation/1.2.5/jpa and here http://www.playframework.org/documentation/1.2.5/guide1 and http://www.playframework.org/documentation/1.2.5/guide2

That's it))

Upvotes: -2

Related Questions