Eduardo Yañez Parareda wrote:I don't like it because you'll have a lot of classes, it's a very fine grain approach. For each operation on DB you'll have a class!, I think if you
have a few different types of operations it would work, but when your app begins to grow up it could be harder to maintain.
More classes, yes, but there are several advantages with this approach
1) You don't have large classes containing several large methods that are often each doing essentially the same thing with slight variations.
2) You can eliminate duplicate boiler plate code by creating DAO abstract command classes for CRUD operations. These classes would call strategies (if necessary) for the slight variations such as selection criteria and populating the domain objects. This makes for nicely cohesive classes that are very testable because they abide by design principles such as IOC, DIP, Hollywood, Open-Close, etc.
3) The client of the DAO can in some cases be abstract, not even knowing what DAO it is calling - just passing along the request type and params, and the command pattern takes care of invoking the right DAO. With the more traditional DAO aproach, your client controller has to interpret the request and hard code a call to a corresponding DAO operation. That means a lot of duplicate client controller code too. With the DAO command approach, some web requests can be handled abstractly from the web server all the way down to the DAO, with no specialized code except for the simple DAO strategies for selection criteria, populating, etc.
4) When you have DAO command classes, they can be composed together as decorators to map to multiple sources. For example, if you need to write to the DB and also to memcached, you need two different mappers.
5) For read operations that attempt to read from cache, the DAO command classes can be composed together following the chain or responsibility pattern. The first DAO, which attempts to read from cache, does not contain the rquested data, will pass the request along to the next DAO in the chain (which reads from the DB), and update itself with the data when it comes back up the chain. Subsequent calls for the same data will not need to go back down the chain of DAOs.
To me, this approach makes a lot of sense. I've always thought it was strange that in JAVA EE, the command pattern and/or DI is used from web server to container, from container to
servlet, from servlet to controller (using front controller pattern), but after that, it stops and the controller has to translate the request into a hard-code DAO call. For more complicated requests, this may be necessary, but not for the simpler ones (of which there are many). I worked on an open source effort for Lockheed Martin that successfully used this approach,
http://github.com/lmco/eurekastreams. It's a facebook-like app for the workplace.
Rohit Agrawal wrote:I don't quite like this approach for some reasons:
- In ServiceImpl : you can't influence the flow of DAOs being called. For e.g. after execution of 1st DAO if I don't want to execute 2nd DAO but execute 3rd DAO, it's hard to have this implemented.
- besides not sure if we can conceptually use DAO. because a Command object can have business logic, however DAOs should only deal with aspects of reading and writing data to db.
As I think you mentioned in a later post, for more complicated services, you can just create a specialized service implementation and hard code which DAO commands are called.
Using DAO commands does not force business logic to be in the DAO. The logic is in still in the service, and also in the factory that wires the DAOs.