My persistent classes are real classes - or not?

04 April 2006

When designing classes for persistence with XPO, it’s easy to be confused about certain aspects, decisions that have to be made about the layout of the class hierarchy. There are two common outcomes that typically result in problems:

  1. The class hierarchy is designed without giving (much) thought to the requirements of XPO and persistence in general. I’m going to refer to this as the non-persistent hierarchy case.
  2. Classes are created as pure data containers, similar to Data Transfer Objects (DTOs), without functionality, and often without being organized in any real hierarchy. This is going to be the DTO case from here on.

The non-persistent hierarchy case

Let’s look at these cases in some detail, beginning with the non-persistent hierarchy case. What are common problems here?

  • Classes implement elaborate creation logic, for example by exposing various constructors for specific purposes and with large numbers of parameters, or by hiding their constructors altogether to force creation by use of static methods. This doesn’t play together with XPO well – it wants to have a constructor with just a Session type parameter.
  • Properties don’t have public setters because setting property values is only allowed for constructors or a set of tightly controlled methods. XPO doesn’t like this because it needs direct access to properties when objects are being loaded from the database.
  • Property setters are implemented to have lots of potential side-effects. This can be a problem because XPO uses the property setters during object loading and and when committing changes from nested units of work, which might not have been anticipated by the class designer. It can also result in performance problems, or if the potential side effects include exceptions being thrown, XPO can react to that by interrupting some process unexpectedly.
  • Algorithms are implemented to work with collections of certain abstract base class types, which might end up being non-persistent when the class hierarchy is handled by XPO. It is not possible to query collections of non-persistent types with XPO, which makes it difficult to select the data for said algorithms.

The DTO case

In this case it is a bit more difficult to enumerate the precise mistakes that are being made, but essentially the persistent classes are treated as equivalents of the standard .NET DataRow – they contain data, but that’s all they are allowed to do, because all functionality relevant to that data is implemented elsewhere. This violates paradigms of OO design and the developer is wasting his time – in extreme cases the benefits of an object/relational mapping system like XPO are small or non-existent.

A warning sign for this case is usually that a very tight coupling can be detected between certain persistent types and other classes. Method calls tend to have effects in the wrong places. Consider the following piece of code:

MyType1 object1 = ... ;
MyType1 object2 = ...;

object1.DoSomething(object2);

What do you expect which objects should be changed, if any, by the call to the DoSomething() method? Right, it should be object1, more often than not. Of course the code in DoSomething() could also set properties of object2 or call further methods. But in a majority of cases, specifically when we’re talking about persistent classes (which are usually closely related to stored data), a call to a method of an object should result in some kind of change to that same object.

After this explanation it should be clear what the warning sign is that was mentioned above: if you find a lot of method calls in your application where changes occur only in the objects that are being passed in, not in the object on which the method is called, then it is very probable that you have implemented functionality in the wrong place.

So what’s the right way?

That’s the nice thing about programming – there’s never a single right way. Some ways are just less wrong than others. My suggestion is, when designing classes for use with XPO, just keep a few things in mind:

  • It is not true that persistent classes don’t have any requirements of their own, above those that OO class hierarchies generally have. The list of common problems in the non-persistent hierarchy section above should give you a good starting point.
  • On the other hand, don’t forget that your persistent classes are really classes, and they can do a lot more than a dumb data container can. Don’t forget you are constructing a hierarchy, not just a single class. Things like virtual and abstract methods can mostly be used in persistent classes just as well as in non-persistent ones.

Do you have any comments on this? I’m sure I forgot to mention something. Please post your feedback below!

Tags
7 comment(s)
Ramiro Bautista
Hi Oliver.
I agree with you when you say "persistent classes are really classes", however i´m confussed respect to validation, i think that the validation code must be in the class and I place this in the beforesave from classes. I have reading another comments from you in another direction, saying that the validation code must be place in another classes.
5 April, 2006
Oliver Sturm (DevExpress)
Hey Ramiro -

Obviously the topic of validation is a lot bigger than could be discussed here in the comments on a post, but I have plans to work on this as one of the upcoming technical articles about XPO.

Not sure if I ever said validation code "must be placed in other classes", but generally I think this is correct - you should use overridden methods like BeforeSave only as a means of defensive programming, and you should structure your code in such a way that the validation code in these methods doesn't find anything under any "normal" circumstances.

In practical scenarios, the topic of validation doesn't end on the border between classes - more often than not you'll find that a given plausible setup of data structures doesn't only define a few rules for correct content of single fields. I like to talk about "plausibility checking" instead of validation to point this out. This is the main reason why I believe that plausibility checking code should not be in the classes themselves. But if it has to be, that's fine with me, as long as it doesn't mix with the persistence mechanisms - plausibility checking is part of business logic, and as such should not interfere with persistence.

Thanks for your comment!
5 April, 2006
Thomas
Is it possible for you to add community forum support?  Many times I am using your products (XtraReports for example) and you have questions about particular issues and fires you're facing in your project RIGHT NOW!  

Having articles is cool, but when will you have forums for people to interact with your engineers and other professionals?
6 April, 2006
Oliver Sturm (DevExpress)
Thomas -
I think we're not going to have this. We have our newsgroups, which are mainly for peer to peer discussion - but the lead developers or program managers or even developers can take part in the discussions to a degree they want. Not every one of our developers feels comfortable taking part in public discussions and we're not going to force anybody. And of course we have to consider that every minute spent by our project team members in newsgroups, or with other support-related communication, is a minute that's not being used to develop our products.

We are committed to doing the things that are best for our customers and that's why we have to find a compromise between limit-less discussions and total silence. We're tentatively moving that borderline back and forth, but I'm pretty sure that a public discussion forum involving a lot more of our r&d stuff than the newsgroups currently do would be a very extreme thing and unjustifiable in many ways.

Re-reading your question I wonder - do you actively use the newsgroups at all? I find that many times they do provide ad-hoc answers to urgent problems for our customers, and the XtraReports one is definitely pretty active. Information about the newsgroups can be found here, if you're interested: http://www.devexpress.com/Support/newsgroups.xml
6 April, 2006
Ramiro Bautista
Hi Oliver:
I post an answer from developer express supor team
"Hi,

We do not recommend that you mix business and DataBase logic.  The validation should be performed in your GUI classes.  We consider that the application works incorrectly if a part of the validation is done within XPO classes.  Please describe your task in detail, we will try to find a solution for you.
Thanks,
Plato
You can check the state of your issue at: https://www.devexpress.com/issue=DQ13947
If you need to you can modify your inquiry and add additional details."

Maybe i´m wrong, but seems to me that Plato is suggested that the XPO classes are "DataBase Logic" as DTOs.
8 June, 2006
Oliver Sturm (DevExpress)
Ramiro,

well yes, I believe you're wrong. Plato isn't saying anything about what the XPO classes should be or which code they should contain - he just says that the validation code shouldn't be in them. As you can see from the other content in this article and in my first comment, I do agree with that. I'm not a black and white kind of person, but I think I said that pretty clearly :-)

Further on, Plato says he'd like to see the validation code in the GUI classes. Well, I certainly don't agree with that, but I assume it's possile that Plato was thinking of a certain kind of application when he made that statement. It seems pretty obvious to me that in a complex application there will be more locations than just "GUI classes" where validation needs to be executed. Even more importantly, a "valid" object state may not even be the same state in all those locations!

So, consequently: in my opinion validation code should live outside the business classes. I've experimented with both approaches in the past and having the code outside simply ended up being the more flexible one in my experience. But regardless of where the code is, the much more important question is actually from where you call it - in an application of any complexity you will end up calling into validation code from more than one place, and so this has to be part of your concept.
28 November, 2006
eXpress App Framework Team

This is post no. 1 in the mini series "10 exciting things to know about XAF". You can find

20 May, 2008

Please login or register to post comments.