以前は、コンストラクタ内でオブジェクトの検証を実行し、検証が失敗したときに例外がスローされました。例えば:私のオブジェクトは、その一貫性を強化し、それが常に有効である保証する責任があるとして、私はこのアプローチを好む一方で通知パターンを使用したドメイン検証
class Name
{
const MIN_LENGTH = 1;
const MAX_LENGTH = 120;
private $value;
public function __construct(string $name)
{
if (!$this->isValidNameLength($name)) {
throw new InvalidArgumentException(
sprintf('The name must be between %d and %d characters long', self::MIN_LENGTH, self::MAX_LENGTH)
);
}
$this->value = $name;
}
public function changeName(string $name)
{
return new self($name);
}
private function isValidNameLength(string $name)
{
return strlen($name) >= self::MIN_LENGTH && strlen($name) <= self::MAX_LENGTH;
}
}
、私は例外の使用について過度に熱心行ったことがありません。上記のような例外の使用を主張する人がいますが、複数のオブジェクトに対して検証を実行するときに返すことができる検証メッセージの数は限られています。たとえば:
class Room
{
private $name;
private $description;
public function __construct(Name $name, Description $description)
{
$this->name = $name;
$this->description = $description;
}
}
class Name
{
public function __construct(string $name)
{
// do some validation
}
}
class Description
{
public function __construct(string $description)
{
// do some validation
}
}
Name
とDescription
の両方が検証に失敗すると、私は両方のオブジェクトのための失敗メッセージ、最初に失敗した方のオブジェクトからだけではなく、単一の例外を返すことができるようにしたいです。
notification patternで少し読んだところ、私はこれが私のシナリオに適していると感じました。私が立ち往生するところでは、どのように検証を実行し、検証が失敗した場合にオブジェクトが無効な状態になるのを防ぐかです。
class Name
{
const MIN_LENGTH = 1;
const MAX_LENGTH = 120;
private $notification;
private $value;
public function __construct(string $name, Notification $notification)
{
$this->notification = $notification;
$this->setName($name);
}
private function setName(string $name)
{
if ($this->isValidNameLength($name)) {
$this->value = $name;
}
}
private function isValidNameLength(string $name)
{
if (strlen($name) < self::MIN_LENGTH || strlen($name) > self::MAX_LENGTH) {
$this->notification->addError('NAME_LENGTH_INVALID');
return false;
}
return true;
}
public function hasError()
{
return $this->notification->hasError();
}
public function getError()
{
return $this->notification->getError();
}
}
私は、上記についていくつかの懸念があります。検証が失敗した場合、そのオブジェクトはまだ構築されるが、その$value
が有効な状態ではありませんnull
ある
- を。
Name
を作成した後、hasError
に電話して、検証エラーが発生したかどうかを確認する必要があります。- 私はドメインオブジェクトを
hasError
/getError
の機能でぼかしていますが、これはわかりやすい機能です。
このパズルの一部が欠落していますか?通知パターンを利用しても、オブジェクトが無効な状態にならないようにするにはどうすればよいでしょうか?
オブジェクトである 'Factory'は' Room'ですか?この 'RoomFactory(文字列名、文字列の説明)'では、 'Name'と' Description'オブジェクトを作成し、それぞれに 'hasError'をチェックして妥当性を判断します。それでも無効な不変量は許されませんか? – Unflux