DDD'yi günlerdir okudum ve bu örnek tasarım konusunda yardıma ihtiyacım var. DDD'nin tüm kuralları beni, etki alanı nesnelerinin uygulama katmanına yöntemler göstermesine izin verilmediğinde nasıl bir şey inşa etmem gerektiği konusunda kafamı karıştırıyor; davranışı düzenlemek için başka nerede? Depoların varlıklara enjekte edilmesine izin verilmez ve bu nedenle varlıkların kendileri devlet üzerinde çalışmalıdır. Sonra bir varlık etki alanından başka bir şey bilmek gerekir, ancak diğer varlık nesneleri de enjekte izin verilmiyor? Bunlardan bazıları benim için anlamlı, bazıları anlamsız. Tüm örneklerin Siparişler ve Ürünler ile ilgili olduğu gibi, tüm örnekleri nasıl oluşturacağınıza dair iyi örnekler bulamadım, diğer örnekleri tekrar tekrar tekrarladım. En iyi örnekleri okuyarak öğreniyorum ve bugüne kadar DDD hakkında edindiğim bilgileri kullanarak bir özellik oluşturmaya çalıştım.
Ne yanlış yaptığımı ve nasıl düzeltebileceğinizi belirtmek için yardımınıza ihtiyacım var, en iyisi "Ben X ve Y yapıyor tavsiye etmem" olarak kod ile her şey zaten sadece belirsiz bir şekilde tanımlanmış bir bağlamda anlamak çok zor. Eğer bir objeyi bir başkasına enjekte edemezsem, onu nasıl düzgün bir şekilde yapacağımı görmek daha kolay olurdu.
Örneğimde kullanıcılar ve moderatörler var. Bir moderatör kullanıcıları yasaklayabilir, ancak bir iş kuralıyla: günde sadece 3. İlişkileri (aşağıdaki kodu) göstermek için bir sınıf diyagramı kurma girişiminde bulundum:
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);
Kullanıcı yetkisinde 'is_banned'
kontrol edilebilecek bir alan olmalı $user->isBanned();
mı? Yasak nasıl kaldırılır? Hiç bir fikrim yok.