[TYPO3-50-general] FLOW3 and DDD

Robert Lemke robert at typo3.org
Thu Jan 22 12:03:53 CET 2009


Hi Nino,

Am 19.01.2009 um 19:06 schrieb Nino Martincevic:

> I am sure I understood how you implemented it. Technically it is  
> easy to
> solve it this way. But I doubt that it is helpful.
>
> Let me take the last example of two (empty) customers C1 and C2.
> You would save them with the repository manager by uisng their hash  
> code.
>
> So e.g. let's take a form where I can register myself on your site.
> I open two windows and two forms and type in exactly the same data on
> page 1.
> I submit both forms. Technically no problem, they are distinguished by
> their hash code. Now I'm on the last page and save.
> What happens now?
>
> Either
> a) I got two Customers in the DB, with two different DB Ids but
> identical data (if there are no other unique constraints).
>
> b) I get an exception in the second form with customer C2 saying that
> such a customer already exists (C1).
>
> So, if you say the first is true then it is just the problem of the
> domain developer, right?
>
> And in the second case it's also his problem but also with a solution
> for avoiding duplicate identical objects being persisted.
>
> That would not avoid the logical constraints clashes given by the
> domain. But it would lead to better software because people could not
> easily create "Object with identity" without identity.
>
> BUT:
> imagine my domain being held in cache or memory, I have such a case
> here, I have in-memory (cached) entities I don't want to persist (they
> are domain events but entities because I have to distinguish same  
> but no
> need for persisting).
>
> I would have a problem with the current solution. Because I'd have
> identical objects that I query by their identity attributes via their
> repository and not their hash code.
>
> What I ask myself: would it be very hard to obtain an unique key from
> the developer before saving it with a repository manager? Technically
> that would be no problem, because you could use again a hash  
> internally,
> but now a combination of the class and the parameters.
>
> I think we are d'accord on what identity means.
> But I'm sure this is an easy change in the Repository Manager at no  
> cost.

You're right, currently it's the domain developer's responsibility to  
check
for duplicates. The abstract repository implementation only takes care  
of
the technical identity but not that defined in the domain.

Take this domain model for example:

/**
  * @entity
  */
class Customer {

    protected $customerNumber;
    protected $firstName;
    protected $lastName;
    protected $platinumCustomer;

}

The framework doesn't know that the customerNumber is used to identify
customers, internally it uses a UUID. Therefore it is possible to  
persist
two customers with the same customerNumber (bad).

It is possible to access the technical identifier by using an  
@identifier
annotation:

/**
  * @entity
  */
class Customer {

    /**
     * @identifier
     */
    protected $customerNumber;

    protected $firstName;
    protected $lastName;
    protected $platinumCustomer;

}

However, this has the bad effect that $customerNumber now must be a UUID
because the Content Repository expects a UUID. Not a nice solution for  
this
case.

So, if we want to add support for checking the true identity of domain  
objects
we need a different approach. While it is still useful to access the  
technical
identity in some cases (to check for duplicates during import / export  
for example)
it must not be mixed up with the identity of the entity.

We could introduce more annotations for that purpose:

/**
  * @entity
  */
class Customer {

    /**
     * Only for technical purposes, properly doesn't belong to a  
domain model
     *
     * @var string
     * @uuid
     */
    protected $uuid;

    /**
     * @var string
     * @identity
     */
    protected $customerNumber;

    /**
     * @var string
     */
    protected $firstName;

    /**
     * @var string
     */
    protected $lastName;

    /**
     * @var boolean
     */
    protected $platinumCustomer;

}

Now the framework knows that no two customers with the same  
$customerNumber may exist.
Imagine we don't have a customer number but instead use the name as  
identity:

/**
  * @entity
  */
class Customer {

    /**
     * @identity
     * @var string
     */
    protected $firstName;

    /**
     * @identity
     * @var string
     */
    protected $lastName;

    /**
     * @var boolean
     */
    protected $platinumCustomer;

}

In this case the framework assures that no Customer with the same  
combination of first name
and last name exists.

Would that be solution of your gusto?

Cheers,
robert



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