はじめに
- 値オブジェクトとはドメインオブジェクトの基本
- 概念自体はシンプルで、システムに登場する金銭や単価といった値をオブジェクトとして定義するもの
PHP(Laravelで書いてみる)
ユーザーを登録する処理で、値オブジェクトを使わない場合と使った場合で比較してみます。
値オブジェクトを使わない場合の処理
class UserRepository extends BaseRepository
{
private crateUser (string $userId, string $name)
{
// 新規ユーザー作成をする処理
}
}
class UserLogic {
private $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
private function createUser()
{
$userId = 'komeda_tarou';
$name = 'コメダ太郎';
$this->userRepository->createUser($userId, $name);
};
}
ユーザー追加のための何気ない処理を書いています。ここでいくつか気になる点をあげるとすると、createUserメソッドに渡す引数の$name
と$userId
の順番を間違えてしまう可能性があります。今回の場合順番を間違えたとしてもどちらも文字列のため保存されてしまいます。
また、userIdの型は今回はstring型を渡す必要がありますが、string型かint型かどうかはロジッククラスからは分かりません。これらを値オブジェクトを使って解決してみます。
値オブジェクトを使う場合の処理
まず、値オブジェクトクラスを作成します。
class UserId
{
private $value;
public function __construct(string $value)
{
$this->value = $value;
}
public function getValue(): string
{
return $this->value;
}
}
class Name
{
private $value;
public function __construct(string $value)
{
$this->value = $value;
}
public function getValue(): string
{
return $this->value;
}
}
上記で作成した値オブジェクトを引数として使うことによって、値を入れ間違う危険が減ります。値オブジェクトを使うように修正してみます。
class UserRepository extends BaseRepository
{
private crateUser (UserId $userId, Name $name)
{
// 新規ユーザー作成をする処理
}
}
class UserLogic {
private function createUser()
{
$userId = new UserId('komeda_tarou');
$name = new Name('コメダ太郎');
$this->userRepository->createUser($userId, $name);
};
}
もし$userId
と$name
に不正な値が入らないように制限をかけたい場合、値オブジェクトクラスの中で、制限をかけることができます。今回はコンストラクタ内に、許可しない値が渡された場合はExceptionを投げるようにしてみます。
値オブジェクトの中で、不正な値が入らないように配慮
- 制限①: $userIdは
_
を含まなければならない - 制限②: $nameは10文字以下でなければならない
class UserId
{
private $value;
public function __construct(string $value)
{
// 制限①: $userIdは`_`を含まなければならない
if (false === strpos($value, '_')) {
throw new Exception();
}
$this->value = $value;
}
}
class Name
{
private $value;
public function __construct(string $value)
{
// 制限② $nameは10文字以下
if (mb_strlen($value) <= 10) {
throw new Exception();
}
$this->value = $value;
}
}
それぞれの制限に対して違反する値が渡されたときは、Exceptionを返すようになりました!
最後に
値オブジェクトは「ルールを定義して、そのルールに反する操作を許容しない」ということをクラスとして定義している。