Application Generates Identity

If the client can't provide the Identity generally, the preferred way to handle the Identity operation is to let the application generate the Identities, usually through a UUID. This is our recommended approach in the case that you don't have a scenario as shown in the previous section.

According to Wikipedia:

The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination. In this context the word unique should be taken to mean practically unique rather than guaranteed unique. Since the identifiers have a finite size, it is possible for two differing items to share the same identifier. This is a form of hash collision. The identifier size and generation process need to be selected so as to make this sufficiently improbable in practice. Anyone can create a UUID and use it to identify something with reasonable confidence that the same identifier will never be unintentionally created by anyone to identify something else. Information labeled with  UUIDs can therefore be later combined into a single database without needing to resolve identifier (ID) conflicts.

There are several libraries in PHP that generate UUIDs, and they can be found at Packagist: https://packagist.org/search/?q=uuid. The best recommendation is the one developed by Ben Ramsey at the following  link: https://github.com/ramsey/uuid because it has tons of watchers on GitHub and millions of installations on Packagist.

The preferred place to put the creation of the Identity would be inside a Repository (we'll go deeper into this in the Chapter 10Repositories:

namespace DddBillingDomainModelOrder;

interface OrderRepository
{
public function nextIdentity();
public function add(Order $anOrder);
public function remove(Order $anOrder);
}

When using Doctrine, we'll need to create a custom Repository that implements such an interface. It will basically create the new Identity and use the EntityManager in order to persist and delete Entities. A small variation is to put the nextIdentity implementation into the interface that will become an abstract class:

namespace DddBillingInfrastructureDomainModelOrder;

use DddBillingDomainModelOrderOrder;
use DddBillingDomainModelOrderOrderId;
use DddBillingDomainModelOrderOrderRepository;

use DoctrineORMEntityRepository;

class DoctrineOrderRepository
extends EntityRepository
implements OrderRepository
{
public function nextIdentity()
{
return OrderId::create();
}

public function add(Order $anOrder)
{
$this->getEntityManager()->persist($anOrder);
}

public function remove(Order $anOrder)
{
$this->getEntityManager()->remove($anOrder);
}
}

Let's quickly review the final implementation of the OrderId Value Object:

namespace DddBillingDomainModelOrder;

use RamseyUuidUuid;

class OrderId
{
private $id;

private function __construct($anId = null)
{
$this->id = $id ? :Uuid::uuid4()->toString();
}

public static function create($anId = null )
{
return new static($anId);
}
}

The main concern about this approach, as you'll see in the following sections, is how easy it is to persist Entities that contain Value Objects. However, mapping embedded Value Objects that are inside an Entity can be tricky, depending on the ORM.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset