gpt4 book ai didi

php - 通过紧密耦合其值对象摆脱实体工厂

转载 作者:搜寻专家 更新时间:2023-10-31 21:09:00 24 4
gpt4 key购买 nike

我的 User 实体值对象松散耦合,因此我使用 UserFactory 来构建来自数据库或创建对象的对象域的全新实体。

是否可以将值对象紧密耦合以便在更新实体及其属性时摆脱它的工厂并让我的应用程序服务因单个值对象实例化逻辑(在能够注入(inject)它们之前)而膨胀?无论如何,值对象不是与其根紧密相关吗?

例如,当我用松耦合版本更新其中一个属性时,我必须先实例化值对象,然后然后注入(inject)它。但在紧密耦合的示例中,我将能够直接输入新值,而无需显式经历 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.
}

最佳答案

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

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

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 应该只接受值对象,并且为了创建“复杂”值对象,您可以创建辅助(工厂)方法或工厂 - 取决于它的复杂程度:

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 - 通过紧密耦合其值对象摆脱实体工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25911146/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com