I too have taken something of a hybrid approach in most cases... I created something called a Function Bean (FB), which for all intents and purposes is really just a DAO. For instance, in one app I have a ClientFB class that has methods like:
ArrayList getClientList(); ClientDTO getClientInfo(String id); boolean saveClient(ClientDTO client); boolean deleteClient(String id); All the typical methods... note that the DTOs are really only for data storage and transpot... there are usually no operations attached (except sometimes for simple things like comparisons and such). In any case, only these FBs know anything about how the data is stored. Then I have a ClientFBHelper class that is where the actual business logic-type things reside, so that the ClientFB winds up just dealing with persistance. So, in it I might have: boolean isClientValid(ClientDTO client); Where it starts to become a little bit of a hybrid is that the FBs don't actually, in many cases, map to real modeled objects. I'd describe them as more mapping to a view of the model. So in my Actions I do things like (in the case of saving a client): ClientFB cfb = fbfactory.get("ClientFB"); ClientFBHelper cfbh = fbhelperfacroty.get("ClientFBHelper"); ClientDTO cdto = new ClientDTO(); PropertyUtils.copyProperties(cdto, actionform); ActionForward af; if (cfbh.isClientValid(cdto)) { if (cfb.saveClient(cdto)) { af = mapping.findForward("goodsave"); } else { af = mapping.findForward("badsave"); } } else { af = mapping.findForward("notvalid"); } return af; The FBs and FBHelpers are gotten from a factory only, so I can control various things easily (i.e., the factory makes sure the beans get set up in the beginning and cleaned up at the end, share a database connection if need be, things like that). There is actually a Struts base Action that instantiates the factories and passes them into execute() and then cleans them up afterwards, but that's kind of outside this particular discussion. I even toyed at one point with the idea of doing all of the above from a config file and reducing the app to a single specialized Action in most places. When you find that most of your Actions look like the above, that's a fairly appealing idea! The nice thing about this setup is that I can test the persistance in the FBs separate from the application and the helper classes separate from the FBs and the app, etc. It's also trivially easy to mock up either to test the app. In this approach, you can have a persistence framework involved or not. We've only recently here decided to use Hibernate across-the-board, so much of our existing apps are straight JDBC. But, converting them to use Hibernate will only require changes in the FBs, everything else remains the same (I've done some pilots to test that theory, and it works out nicely). So, to Rick's original point, I guess this really isn't as OO as we all started out learning :) But, as with most things it's an evolution of understanding... I'd be willing to bet that 5 years from now we won't be writing apps like we do today either and we'll wonder why we ever did things this way or that. -- Frank W. Zammetti Founder and Chief Software Architect Omnytex Technologies http://www.omnytex.com On Thu, August 4, 2005 12:05 pm, Mark Benussi said: > That's how my persistence framework goes. > > All my data extends a data object which makes public CRUD methods that > accept a persister, you can then have File persisters, Database persisters > etc. An employee shouldn't have any knowledge of how they persist in an > enterprise IMHO. All that logic is placed in the persister. > > Employee employee = new Employee(); > employee.setKey(1); > > // Reads and populates an employee. > EmployeeDBPersister dbPersister = new EmployeeDBPersister(conn); > employee.read(dbPersister); > > // Writes the employee to a file. > EmployeeFilePersister filePersister = new EmployeeFilePersister(file); > employee.create(filePersister); > > I hate DAO's. The company I work for uses them. Basically one class to do > all the logic related in any way shape of form to a valgue amount of > database tables. They then change a column on a table and wonder why there > code is a nightmare to fix. If you have one Persister responsible for a > table then you change the four pieces of sql for create read update and > delete and you are laughing. > > In answer to the collections comment, I have managers which my application > interfaces with to get collections. Basically something like > > EmployeeManager manager = new EmployeeManager(); > ArrayList employees = manager.getEmployees(); > > And the method gets all the keys in a separate piece of SQL and then calls > the code I have shown above. > > -----Original Message----- > From: Rick Reumann [mailto:[EMAIL PROTECTED] > Sent: 04 August 2005 16:15 > To: Struts Users Mailing List > Subject: Re: DTOs are evil > > Michael Jouravlev wrote the following on 8/3/2005 9:07 PM: >> http://www.theserverside.com/news/thread.tss?thread_id=35233 >> > > Just curious what are Rod's exact views on the DTO? I searched for DTOs > on that link you posted but only saw posts by other people. > > I do agree, though, with what others have said that DTOs/ValueObjects > aren't really that OO. It's funny that the subject comes up because I > was a late bloomer to the programming world (started about 6 years and > was a waiter and science teacher before that:), and when I first started > reading the Java books and then applying that to what I was > reading/seeing in JSP projects I was on, the concepts did seem to > conflict. > > What I mean is take the concept of an "Employee." In almost all web > applications you see the EmployeeDTO being passed to the DAO... > > employeeDAO.updateEmployee( employee ); > > From what I recall the real OO way would be... > > employee.update(); > > and employee takes care of updating itself. > > From an OO perspective I don't see a problem having an Employee object > that has a DAO inside that takes care of persistence. I do have a couple > questions though about OO design if this approach is used... > > 1) Where do you encapsulate getting Collections back of your objects? > For example an Employee object has CRUD methods, but what about you when > you need a List of Employees? Do you make an EmployeeList object that > has methods getEmployees? Do you maybe just 'cheat' and add a getList or > getEmployees method directly to the Employee object? > > 2) It also seems a bit heavy to return Collections of pretty heavy > objects. (Each Employee since it's not a simple VO could be a large > object - although by large I just mean having a bunch of methods in it > etc - I'm not so sure it would be large footprint-wise if just the > properties were being filled in the case of a list - so bottom line is > maybe the extra stuff in the object doesn't matter much? > > Side note... > > 3) Even from an OO perspective, you always hear about encapsulating > unique behaviors to make things reusable, so in a sense couldn't you > consider the 'properties' of an Employee 'unique' or, if not the > properties, the CRUD stuff is 'sort of' unique? If this is the case, you > could make an argument for separating out the properties into another > object (DTO/VO) separate? > > > -- > Rick > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]