Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 通过紧密耦合实体工厂的值对象摆脱实体工厂_Php_Entity_Domain Driven Design_Coupling_Value Objects - Fatal编程技术网

Php 通过紧密耦合实体工厂的值对象摆脱实体工厂

Php 通过紧密耦合实体工厂的值对象摆脱实体工厂,php,entity,domain-driven-design,coupling,value-objects,Php,Entity,Domain Driven Design,Coupling,Value Objects,我让我的Userentity-value对象松散耦合,因此每当对象来自数据库或在域中创建全新的实体时,我都使用UserFactory来构建对象 在更新实体及其属性时,是否可以将值对象紧密耦合起来,这样我就可以摆脱它的工厂,让我的应用程序服务充斥着单个值对象实例化逻辑(在能够注入它们之前)?值对象与它们的根不是紧密相关吗 例如,当我用松耦合版本更新其中一个属性时,我必须首先实例化value对象,然后注入它。但是在紧密耦合的示例中,我可以直接输入新值,而不必显式地经历实例化VO的过程 示例: //

我让我的
User
entity-value对象松散耦合,因此每当对象来自数据库或在域中创建全新的实体时,我都使用
UserFactory
来构建对象

在更新实体及其属性时,是否可以将值对象紧密耦合起来,这样我就可以摆脱它的工厂,让我的应用程序服务充斥着单个值对象实例化逻辑(在能够注入它们之前)?值对象与它们的根不是紧密相关吗

例如,当我用松耦合版本更新其中一个属性时,我必须首先实例化value对象,然后注入它。但是在紧密耦合的示例中,我可以直接输入新值,而不必显式地经历实例化VO的过程

示例:

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

$user->setFullName($fullName);

// Updating User's name (tightly coupled version)
$user->setFullName('John', 'Doe');
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.
}
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.
}
松耦合:

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

$user->setFullName($fullName);

// Updating User's name (tightly coupled version)
$user->setFullName('John', 'Doe');
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.
}
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.
}
紧密耦合:

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

$user->setFullName($fullName);

// Updating User's name (tightly coupled version)
$user->setFullName('John', 'Doe');
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.
}
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.
}

我认为这个例子过于简单,没有显示问题的真实程度。我尝试添加更多的场景,以更好地演示“松散”和“紧密”耦合解决方案之间的区别

使用复杂的值对象表明,构建值对象不是“setter”的职责,因为要设置日期,您需要区域设置(或者让我们设想其他值——只是为了演示),而不仅仅是日期的字符串值。因此,将日期作为值对象传递更有意义,也更清楚地表明了意图

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;
    }
}
正如您所看到的,User::setDateOfBirth2()方法看起来不正确——它有两个职责,因此破坏了SRP。如果需要使用Zend_date对象设置日期,则必须添加另一个方法。在下一个示例中,您可以看到setter应该只接受Value对象,对于“复杂”值对象的创建,您可以创建一个helper(factory)方法或一个factory-这取决于它的复杂程度:

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));

想知道你得到了什么样的答案。PHP没有其他平台所拥有的所有奇特的数据传输对象生成工具。对于我自己来说,当我使用值对象时,我会尝试保持“纯粹”,并使用您的第一种方法。我怀疑您正试图在表单中直接使用DDD对象之类的?@Cerad。我可以使用第一种方法,但在我通过注入实体来实际更新实体之前,必须先实例化各个值对象(对于我要更新的属性),这会使代码膨胀。第二种方法是淘汰它,以及它的工厂。由于值对象往往与其实体不紧密相关,我只是想知道是否也可以将它们紧密耦合。是的。我有点作弊,允许我的Name-value对象是可变的$user->getName()返回名称值对象的克隆。然后,我可以更改各个属性并使用$user->changeName($name)进行更新。但总的来说,我不得不说DDD并不过分担心代码膨胀。+1我看到的唯一例外是,如果VO创建需要来自实体的大量数据,那么最好将VO创建完全委托给实体