며칠 동안 DDD에 대해 읽었으며이 샘플 디자인에 도움이 필요합니다. DDD의 모든 규칙은 도메인 객체가 응용 프로그램 계층에 메소드를 표시 할 수없는 경우 어떻게 아무것도 구축 해야하는지에 대해 매우 혼란스럽게 만듭니다. 행동을 조정할 다른 곳? 리포지토리를 엔터티에 주입 할 수 없으므로 엔터티 자체가 상태에서 작동해야합니다. 그러면 엔터티가 도메인에서 다른 것을 알아야하지만 다른 엔터티 개체도 주입 할 수 없습니까? 이 중 일부는 나에게 의미가 있지만 일부는 그렇지 않습니다. 모든 예제가 주문 및 제품에 관한 것이므로 다른 예제를 계속 반복하면서 전체 기능을 빌드하는 방법에 대한 좋은 예를 아직 찾지 못했습니다. 나는 예제를 읽음으로써 가장 잘 배우고 지금까지 DDD에 대해 얻은 정보를 사용하여 기능을 만들려고했습니다.
나는 내가 잘못한 것을 지적하고 그것을 고치는 방법을 지적하기 위해 당신의 도움이 필요하다. 가장 바람직하게는 "X와 Y를 추천하지 않을 것이다"는 모든 것이 이미 막연하게 정의 된 상황에서 이해하기가 매우 어렵 기 때문에 코드를 사용하는 것이 가장 바람직하다. 다른 엔터티에 엔터티를 주입 할 수없는 경우 엔터티를 올바르게 수행하는 방법을 쉽게 알 수 있습니다.
이 예에는 사용자와 중재자가 있습니다. 중재자는 사용자를 차단할 수 있지만 비즈니스 규칙은 하루에 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);
사용자 엔터티에 확인할 수있는 'is_banned'
필드 가 있어야합니까 $user->isBanned();
? 금지를 제거하는 방법? 나도 몰라