私は数日間DDDについて読みましたが、このサンプルデザインの支援が必要です。ドメインオブジェクトがアプリケーション層にメソッドを表示することを許可されていない場合、DDDのすべてのルールにより、どのように構築するかについて非常に混乱しています。行動を調整する他の場所は?リポジトリーをエンティティーに注入することは許可されていないため、エンティティー自体が状態で動作する必要があります。次に、エンティティはドメインから何か他のものを知る必要がありますが、他のエンティティオブジェクトも注入することはできませんか?これらのことのいくつかは私には理にかなっていますが、いくつかはそうではありません。すべての例は注文と製品に関するものであり、他の例を繰り返し繰り返しているため、機能全体を構築する方法の良い例をまだ見つけていません。私は例を読むことで最もよく学び、これまでにDDDについて得た情報を使用して機能を構築しようとしました。
私が間違っていることとそれを修正する方法を指摘するためにあなたの助けが必要です。エンティティを別のエンティティに注入できない場合、適切に実行する方法を簡単に確認できます。
私の例では、ユーザーとモデレーターがいます。モデレーターはユーザーを禁止できますが、ビジネスルールがあります:1日あたり3人のみです。関係を示すためにクラス図を設定しようとしました(以下のコード):
interface iUser
{
public function getUserId();
public function getUsername();
}
class User implements iUser
{
protected $_id;
protected $_username;
public function __construct(UserId $user_id, Username $username)
{
$this->_id = $user_id;
$this->_username = $username;
}
public function getUserId()
{
return $this->_id;
}
public function getUsername()
{
return $this->_username;
}
}
class Moderator extends User
{
protected $_ban_count;
protected $_last_ban_date;
public function __construct(UserBanCount $ban_count, SimpleDate $last_ban_date)
{
$this->_ban_count = $ban_count;
$this->_last_ban_date = $last_ban_date;
}
public function banUser(iUser &$user, iBannedUser &$banned_user)
{
if (! $this->_isAllowedToBan()) {
throw new DomainException('You are not allowed to ban more users today.');
}
if (date('d.m.Y') != $this->_last_ban_date->getValue()) {
$this->_ban_count = 0;
}
$this->_ban_count++;
$date_banned = date('d.m.Y');
$expiration_date = date('d.m.Y', strtotime('+1 week'));
$banned_user->add($user->getUserId(), new SimpleDate($date_banned), new SimpleDate($expiration_date));
}
protected function _isAllowedToBan()
{
if ($this->_ban_count >= 3 AND date('d.m.Y') == $this->_last_ban_date->getValue()) {
return false;
}
return true;
}
}
interface iBannedUser
{
public function add(UserId $user_id, SimpleDate $date_banned, SimpleDate $expiration_date);
public function remove();
}
class BannedUser implements iBannedUser
{
protected $_user_id;
protected $_date_banned;
protected $_expiration_date;
public function __construct(UserId $user_id, SimpleDate $date_banned, SimpleDate $expiration_date)
{
$this->_user_id = $user_id;
$this->_date_banned = $date_banned;
$this->_expiration_date = $expiration_date;
}
public function add(UserId $user_id, SimpleDate $date_banned, SimpleDate $expiration_date)
{
$this->_user_id = $user_id;
$this->_date_banned = $date_banned;
$this->_expiration_date = $expiration_date;
}
public function remove()
{
$this->_user_id = '';
$this->_date_banned = '';
$this->_expiration_date = '';
}
}
// Gathers objects
$user_repo = new UserRepository();
$evil_user = $user_repo->findById(123);
$moderator_repo = new ModeratorRepository();
$moderator = $moderator_repo->findById(1337);
$banned_user_factory = new BannedUserFactory();
$banned_user = $banned_user_factory->build();
// Performs ban
$moderator->banUser($evil_user, $banned_user);
// Saves objects to database
$user_repo->store($evil_user);
$moderator_repo->store($moderator);
$banned_user_repo = new BannedUserRepository();
$banned_user_repo->store($banned_user);
Userエンティティには、'is_banned'
チェックできるフィールドが必要$user->isBanned();
ですか?禁止を解除する方法は?何も思いつきません。