The Lego Process Active Record Design Pattern

Second only to the Active Event Design Pattern, the Active Record design pattern is probably the mos...
The Lego Process Active Record Design PatternSecond only to the Active Event Design Pattern, the Active Record design pattern is probably the most important pattern - and difficult to get right - in the Lego Software Process.



Most readers here are hopefully familiar with the Active Record Design Pattern as originally described by Martin Fowler in his book "Patterns of Enterprise Application Architecture". The Lego Process has adopted Active Record as its name for its data-storage abstraction layer. There are however some few, yet important, differences between the AR pattern as described by Martin Fowler and the way the Lego Software Process implements it. First of all it is imperative that you have a "loosely coupled" database schema. This effectively means that the physical structure of your database must not in any ways be dependent upon your class hierarchy. The reason is pretty obvious when you think of the primary goal of the Lego Process, which is to be able to create a perfect modularized design of your applications.

This means that whenever you've created a new Module with a couple of associated Active Record classes for storing data, you should be able to put that Module into any application you wish, without demanding any changes to the physical structure of your database. Without this property, you do not have a "modular design" - which is the goal of the Lego Process.

A couple of days ago, I blogged about one way you can achieve this loosely coupled database by creating a generic database.

There are a couple of other interesting things to this however, first of all what's the logical relationship between your objects in such a hierarchy...

One to One/Many relationships


This is the first one that strikes you when you start out implementing something like this. One way to illustrate such class hierarchy is by imagine a car. The car have one engine. This makes a class hierarchy that resembles something like this;

class Engine
{
...
}

class Car
{
Engine engine;
}


Logically if we have a car object, and then we remove this car out of our database, maybe it was stolen or something, then also the engine will obviously have to be removed from our database.

So if we delete our car by doing something like this;


Car c = Car.SelectByID(1);
c.Delete();


Then obviously also the Engine object must be deleted from the database.

The same is true for lists of objects which are children to a Car, like for instance the wheels of our car.

If we think about this we come into some samples which are quite intuitive to understand from a logical point of view, but might be challenging from a purely "code perspective". Like for instance imagine this;


Car c = new Car();
c.engine = new Engine();
c.save();

// Now there should be created a Car instance
// and an Engine instanse in our database...
// However, imagine this...

Car c2 = new Car();
c2.engine = c.engine;
c2.save();


In the above sample the first car ("c") will actually *LOOSE* its Engine object. So we can actually change one object by changing another object. Which creates dependencies between objects.

Logically this makes perfect sense, however in regards to code we tend to think that the above scenario isn't "correct". However the above scenario IS correct! If you have an "IsOwner" relationship, then by adding a child object into another parent object than it originally existed within SHOULD remove the object from its first parent relationship...

Many to One/Many


However there are alternative relationships which does not have these properties. Meaning where one object might belong to several different objects.

A nice real world example here could be "the driver" of a car. Imagine this;


class Person
{
}

class Car
{
[IsNotOwner]
Person driver;
}

Person me = new Person();
me.save();

Car c = new Car();
c.driver = me;
c.save();

// Then we delete the car...
c.delete();



If we delete the car this time, then obviously we should NOT delete the person. I think your wife would be pretty upset if someone stole her car, and as a consequence she stopped existing ...

...although I am pretty certain that some of my male readers here could see some great samples for when this would be a nice to have feature ... ;)

The point here is that this is not a "OneToX" relationship, but in fact a "ManyToX" relationship. Logically this makes perfect sense, since every Person might be the driver for more than one Car. So whenever you have something that is not "owned" by something else, then it is a "ManyToX" relationship, even though most people can't afford more than one car. While everytime you've got something which is "owned", it must ba a "OneToX" relationship. And in fact this can be described as two different relationships, period...!

In fact a general rule is also quite easy to deduct out of this, which goes like this;

"If an object is 'owned' by another object, then changes to the object 'owning' the child object might have side-effects to the 'child' object. And changes to the 'child object' might have side-effects for the 'parent' object. However if an object is NOT owned by another object then no changes to neither the 'parent' nor the 'child' object will have ANY consequences for the other."

This means that if we have an "IsOwner" relationship, any "child" object should be saved and updated. If we have a "IsNotOwner" relationship, then saving, updating and deletion should never change the child object.

And it's really that simple :)

.t

Published Sun 16.Aug 09 - viewed 273 times - bookmarked 0 times

/.~ polterguy.blogspot.com


Header of Comment
Comment

Commenting as...


    0 comments in article...





    @ra_ajax_thomas
    There are 174 articles, 163 comments and 7 registered users around here