views:

142

answers:

3

I used to have a Data Access Layer that take the object by parameter and handle with abstraction the type of persistence required. At my new job, the architect is thinking to implement CRUD operation (load..save..delete..update) into all model object. Those method would have an object by parameter that will handle the saving of the object. Exemple : load(IPersistence persistence). I have some doubt about the extensibility and that each model object would have to implement all load,save,delete,update method.

What is the best approach?

+4  A: 

I guess that's the eternal question and both approaches do have their pros and cons and lots of followers who swear by them.

The repository approach that you seem to favor (having a Repository/Gateway whatever you call it) to handle the CRUD operations makes your actual business classes smaller and leaner, since they probably only contain data and possibly validation / business rules.

In this case, you'd implement the CRUD operations once - but most likely once for each type of object you're dealing with.

On the other hand, the smart business object approach might argue that CRUD operation on a given entity are specific to that entity anyway, so the code to select, update, delete such an entity is always going to be specific, so it might as well reside inside that object itself.

In this case, you'd implement the CRUD operations once for each object class - I don't see any big disadvantage over the repository approach in this case, really.

I personally lean towards the repository approach myself today, but I do also see benefits in the "smart business object" approach - both are valid, and I guess you'll just have to either convince your new architect of your position, or get to terms with a different approach.

Marc

marc_s
I would add that the basic cases of CRUD can be implemented just once in a generic repository (depending on the language), and thus you only need to implement specialized methods for each entity going forward. (This may appy to smart business objects too).
mgroves
+3  A: 

I think that, in both cases, the implementation should not be repetitive, but implemented only once and inherited (for example) as needed.
Subclasses and their methods would only be needed for non-standard jobs (like custom queries, with their custom parameters).


Now the question amounts to the POJO philosophical debate. Let me try to phrase it in my own words ;-) :

  1. considering that the model is specific to each specific problem and therefore each application
  2. considering that many aspects are required for the model : persistance is one aspect required for a model, along with validation, documentation, user-interface components and messages, user-suggestions, migration between versions ...
  3. considering that the model alone is hard enough to understand, maintain and so on alone, without all aspects be merged
  4. you deduce that any aspect should be externalized from the model objects.

Actually, we only externalize things that are complex (typically, require some coding), and keep on the Pojo things that are very simple (typically declarations, often using Annotations).


Another huge advantage of having no technical superclass for the model is that the model can be used as its own "data transfer object" to carry that information between systems :

  1. between layers
  2. between JVMs (via Serialization), for example between machines

If our model classes would have technical superclasses, they wouldn't be useful in such various contexts. For example:

  1. Persistance on an model object is often usable only in some layer (in the architectural choices). For example, only the Business Layer would have access to the Data Layer to persist.
  2. During data migration from one machine to another, each machine could work on its own database. Thus, the model objects can be transfered freely if they don't carry pointers to the database ; each serveur should use its own database. For the same model object, variation is possible on other aspects, which is facilitated if the aspects are not carried by the same object.
KLE
+2  A: 

DAL all the way.

You want to be able to isolate your transactions so the objects shouldn't be aware of their persistence. Otherwise the code can tend to an unmaintainable nightmare where objects can activate database round trips and it is difficult to roll a number of transactions into one atomic action.

I found out this the hard way. :)

Quibblesome