Open10
ドメインオブジェクトなEntityのライフサイクルってどうやって表現する?【PHP】
きっかけの記事
もやもやが晴れた。
HogeEntityInterface でライフサイクルを問わない共通な何かを設定する?
<?php
interface HogeEntityInterface
{
}
- 新規作成を想定しているので new NewHogeEntity(1 , 2, 3) でしか生成出来ない
- バリデーションは__construct内部で必須
- パラメータが増えてきたら、Builderパターンの利用も検討する
- 識別子は外から渡す? Entityで生成する。。。?
- 新規生成時に識別子の概念いらなくない?
- そもそも識別は永続化層での都合だから、ここではいらなくない。。?
<?php
class NewHogeEntity implements HogeEntityInterface
{
/**
* @var int
*/
private static int $basicInteger = 5;
/**
* @param int $hoge1
* @param int $hoge2
* @param int $hoge3
* @throws Exception
*/
public function __construct(
private int $hoge1,
private int $hoge2,
private int $hoge3
) {
$this->validateParameter($hoge1);
$this->validateParameter($hoge2);
$this->validateParameter($hoge3);
}
/**
* @param int $hoge
* @throws Exception
*/
private function validateParameter(int $hoge): void
{
$randomInteger = random_int(1, 10);
if (self::$basicInteger < $randomInteger) {
throw new InvalidArgumentException($hoge);
}
}
/**
* @return int
*/
public function getHoge1(): int
{
return $this->hoge1;
}
/**
* @return int
*/
public function getHoge2(): int
{
return $this->hoge2;
}
/**
* @return int
*/
public function getHoge3(): int
{
return $this->hoge3;
}
}
Getter撲滅にこだわるならこれかな。。
- DBとかの永続化層から生成するためにつかう
- constructではバリデーションは行わないなぜなら、ここで行ってしまうと、DBにデータがあるにも関わらず、Entityが生成出来ないから。。
- 識別子は必須。更新後の永続化で絶対に迷子になる。。
- たとえば永続仮想の都合でupdateするのが、delete insertするのか。識別子があればどちらでも対応はできる
- setterメソッドでバリデーションをする。DBからデータを取得したときではなく、データを変更する際に何かしらの仕様を強制できるから。
- updateHoge()とか、データを更新、変更するという意図が伝わるような命名がいいかも
- そもそもミューターブル。イミュータブルにする意味ナッシング。。。
- idを更新、変更する意味はない。。
<?php
class ReconstructHogeEntity implements HogeEntityInterface
{
/**
* @var int
*/
private static int $basicInteger = 5;
/**
* @param int $id
* @param int $hoge1
* @param int $hoge2
* @param int $hoge3
*/
public function __construct(
private int $id,
private int $hoge1,
private int $hoge2,
private int $hoge3
) {
}
/**
* @throws Exception
*/
private function validateParameter(int $hoge): void
{
$randomInteger = random_int(1, 10);
if (self::$basicInteger < $randomInteger) {
throw new InvalidArgumentException($hoge);
}
}
/**
* @param int $hoge1
* @return ReconstructHogeEntity
* @throws Exception
*/
public function setHoge1(int $hoge1): ReconstructHogeEntity
{
$this->validateParameter($hoge1);
$this->hoge1 = $hoge1;
return $this;
}
/**
* @param int $hoge2
* @return ReconstructHogeEntity
* @throws Exception
*/
public function setHoge2(int $hoge2): ReconstructHogeEntity
{
$this->validateParameter($hoge2);
$this->hoge2 = $hoge2;
return $this;
}
/**
* @param int $hoge3
* @return ReconstructHogeEntity
* @throws Exception
*/
public function setHoge3(int $hoge3): ReconstructHogeEntity
{
$this->validateParameter($hoge3);
$this->hoge3 = $hoge3;
return $this;
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return int
*/
public function getHoge1(): int
{
return $this->hoge1;
}
/**
* @return int
*/
public function getHoge2(): int
{
return $this->hoge2;
}
/**
* @return int
*/
public function getHoge3(): int
{
return $this->hoge3;
}
}
最後は、DeleteHogeEntity
- 普通にIDをしてして消せばいいと思っていた。
- いや。。削除条件とかあるやん。。。
- Entityとしてつくるか。。
- new DeleteHogeEntity が生成されたときは削除条件は満たしている
- ただ、よくある例で、ある利用者が削除できるのは自分が作ったデータのみの場合はどうするか。。
- 削除しようとするIDと削除できるIDをEntityに含める?
repository に メソッドをはやして、 findEntityToBeDeleted(SomeDto $dto): DeleteHogeEntity にして、返り値を Entity にすれば良さそう。
そして、delete(DeleteHogeEntity $entity) にすれば行けそうだな
永続層の検索では動作主を識別するID, 削除対象の識別IDを使って検索し、それとは別に削除条件をまとめたやつを含めてDeleteHogeEntityを返せば良さそう?
DeleteEntityに削除条件を渡して、constructorで削除条件のバリデーションを行う。Entityが生成できたら削除できるものとして扱って、削除処理を行うとかよさそう