Getting rid of the Entity factory by tightly tying its Value objects

I have User

loosely coupled entity object objects and because of this I use UserFactory

to create an object whenever it comes from the database or when creating an entirely new object in the domain.

Would it be nice to tightly couple the value objects so I can get rid of its Factory and have my application services bloated with individual value object creation logic (before they could inject them) when updating the object with its properties? In any case, aren't value objects tightly bound to their root?

For example, when I update one of the properties with a loosely linked version, I will need to create a value object first and then inject it. But in a tightly coupled example, I could just inject new values ​​directly, without going through the explicit VO instantiation process.

Example:

// Updating User name (loosely coupled version)
$firstName = new FirstName('John');
$lastName  = new LastName('Doe');
$fullName  = new FullName($firstName, $lastName);

$user->setFullName($fullName);

// Updating User name (tightly coupled version)
$user->setFullName('John', 'Doe');

      

Loosely linked:

class User extends Entity
{
    private $fullName;
    private $email;

    public function getFullName()
    {
        return $this->fullName;
    }

    public function setFullName(FullName $fullName)
    {
        $this->fullName = $fullName;

        return $this;
    }

    public function getEmail()
    {
        return (string) $this->email;
    }

    public function setEmail(Email $email)
    {
        $this->email = $email;

        return $this;
    }

    // etc.
}

      

Tightly connected:

class User extends Entity
{
    private $fullName;
    private $email;

    public function getFullName()
    {
        return $this->fullName;
    }

    public function setFullName($firstName, $lastName)
    {
        $firstName      = new FirstName($firstName);
        $lastName       = new LastName($lastName);
        $this->fullName = new FullName($firstName, $lastName);

        return $this;
    }

    public function getEmail()
    {
        return (string) $this->email;
    }

    public function setEmail($email)
    {
        $this->email = new Email($email);

        return $this;
    }

    // etc.
}

      

+3


source to share


1 answer


I think the example is very simplistic and doesn't show the true extent of the problem / question. I am trying to add more scripts that better demonstrate the difference between loosely coupled and tightly coupled solutions.

Value , Value "setter", locale ( - ), . , .

class User extends Entity
{

    private $dateOfBirth;

    public function setDateOfBirth(\Zend_Date $date)
    {
        $this->dateOfBirth= $date;
    }

    public function setDateOfBirth2($date = null, $part = null, $locale = null)
    {
        $date = new \Zend_Date($date, $part, $locale);

        $this->dateOfBirth = $date;
    }
}

      



As you can see, the User :: setDateOfBirth2 () method looks wrong - it has two responsibilities and thus breaks the SRP. And if you need to set the date using Zend_Date object, you have to add another method. In the following example, you can see that the setter should only accept a Value object, and to create "complex" Value objects you can either create a helper method (factory) or a Factory - depending on how complex it is:

class User extends Entity
{

    private $dateOfBirth;

    public function setDateOfBirth(\Zend_Date $date)
    {
        $this->date = $date;
    }

    public function createDate($date = null, $part = null, $locale = null)
    {
        return new \Zend_Date($date, $part, $locale);
    }
}

$user = new User;

$user->setDateOfBirth($dateOfBirth);

// or

$user->setDateOfBirth($user->createDate($date, $part, $locale));

      

+2


source







All Articles