[TYPO3-50-general] FLOW3 and DDD

Nino Martincevic don at zampano.com
Sat Jan 24 23:32:44 CET 2009


Hi Flow3 team and followers of this thread!

Karsten Dambekalns wrote:
> On 23.01.2009 11:07 Uhr, Nino Martincevic wrote:
>> It seems to be already implemented!
>> At least the docs says this, had no time to check out the code.
>> I'll start a new thread later today for some technical and usage questions.
> 
> Please do. It seems the docs promise more than the code does. ;)

Oh, that's very sad, now I'm really disappointed.
;-)

Here are my announced thoughts and ideas for the implementation of 
checking the Identity for Entities for the Flow3 Persistance Manager.

I also compiled two small blog entries regarding this problem. They are 
in german but most readers of this list seem to know that language :-)
Part 1 is the description of the problem field, what is an Identity and 
how one could compare the identity of entities. It's for those who are 
not that firm with the DDD concept.
Part 2 is the drawing of a solution, and the solution part is almost 
identical with answer that follows in this post.
Here's the link: 
http://www.zampano.com/blog/archives/4-Identifizieren-Sie-sich!-Teil-1.html

First, a small excurs for some followers I find important to outline here:
Before I heard of Flow3 and started with DDD I also experienced most of 
the problem you have and I also have not been able to solve it all 
satisfying for me yet.
But one has to mention here that DDD is not meant for every kind of 
application. If your domain is full of behaviour and states then for me 
there is no alternative. But there are always parts in your application 
where DDD does not help you, it is not well-suited for simply CRUD- or 
reporting domains. And reporting also means showing the UI lists or 
collections of static data. SQL is perfect for that, so use it.
You should see DDD as best tool for CUD, the R must not but should be 
done elsewhere in most cases.

Ok, back to the game:

I took a look at the current implementation in Flow3, you use 
splObjectManager for the storage of objects. It adds objects by first 
comparing them (with SplObjectStorage::contains).
That method uses the === comparison ($object === $obj).

As you know or may guess, you simply cannot do if($object1 == $object2) 
  or if($object3 == $object3) on Entities, because you don't compare its 
values but its identity.

Example:

class Foo implements IEntity
{
	/* @identity */
	var $identityVar;
	var $name;
	var $address;
}

$foo1 = new Foo;
$foo1->$identityVar = 3;
$foo1->$name = 'Jack Daniels';

$foo2 = new Foo;
$foo1->$identityVar = 3;
$foo1->$name = 'John Doe';

In the sense of an DDD Entity $foo1 and $foo2 are identical although 
their values are different, but not their identity!
So, a comparison within splObjectStorage would give a wrong result, 
FALSE. You simply cannot compare an Entity in DDD with just comparing 
their values.

A possible solution I use is to provide the Entities with a method to 
compare themselves. In my recent projects every Entity implements 
IEntity or an inherits from IAggregateRoot and provides a 
sameIdentityAs() method.

Example:

public function sameIdentityAs(Entity $other)
{
	return $other != null && 
$this->identityVar()->sameIdentityAs($other->identityVar());
}

where in this example identityVar is the identity (returned by a getter).

This could be as complex as needed:

function sameIdentityAs(Entity $other)
{
	return $other != null
		&& $this->identity()->sameIdentityAs($other->identity())
		&& $this->identityEntity()->sameIdentityAs($other->identityEntity())
		&& 
$this->identityValueObject()->sameValuesAs($other->identityValueObject());
}

identityEntity would also have the method sameIdentityAs() and so on, a 
recursive comparison of all included parts (as you see: for value 
Objects I use another method).

Naturally, you have to take care of recursions not leading to a 
deadlock. But that shows a probably bad or critical design anyway...

The question now is: how to add this to Flow3?

Like mentioned, personally I solved it with defining two interfaces 
(IEntity and IValueObject), they both enforce the implementation of such 
comparison methods. They provide and check itself and so I have the 
possible complexity of that issue where it belongs to, data and 
knowledge in one place. All this is not my invention, it's a quite 
common standard in many DDD projects, though surely not the only way to 
do it.

I'm not very firm with AOP and annotations though, don't know if this 
could be done easier some way with their aid.
Perhaps a combination with Reflections could play the game.

Hope, you could get some ideas or were affirmed in some of your ideas 
reading this.
If you should have a better solution, let me know, I'm always willing to 
improve my code...:-)

Cheers,
Nino


More information about the TYPO3-project-5_0-general mailing list