ฉันได้อ่านเกี่ยวกับ DDD มาหลายวันแล้วและต้องการความช่วยเหลือในการออกแบบตัวอย่างนี้ กฎทั้งหมดของ DDD ทำให้ฉันสับสนมากกับวิธีที่ฉันควรจะสร้างอะไรเลยเมื่อวัตถุโดเมนไม่ได้รับอนุญาตให้แสดงวิธีการในชั้นแอพลิเคชัน; มีที่ไหนอีกที่จะจัดการกับพฤติกรรม? ที่เก็บไม่ได้รับอนุญาตให้ถูกฉีดเข้าไปในเอนทิตีและเอนทิตี้ของตัวเองจึงต้องทำงานกับรัฐ ถ้าอย่างนั้นเอนทิตีต้องรู้อะไรจากโดเมน แต่วัตถุเอนทิตีอื่น ๆ ไม่ได้รับอนุญาตให้ฉีด? บางสิ่งเหล่านี้มีเหตุผลสำหรับฉัน แต่บางอย่างไม่ ฉันยังไม่พบตัวอย่างที่ดีของวิธีสร้างคุณลักษณะทั้งหมดเนื่องจากทุกตัวอย่างเกี่ยวกับคำสั่งซื้อและผลิตภัณฑ์ทำซ้ำตัวอย่างอื่น ๆ ซ้ำแล้วซ้ำอีก ฉันเรียนรู้ได้ดีที่สุดจากการอ่านตัวอย่างและพยายามสร้างคุณสมบัติโดยใช้ข้อมูลที่ฉันได้รับเกี่ยวกับ DDD ในตอนนี้
ฉันต้องการให้คุณช่วยชี้ให้เห็นสิ่งที่ฉันทำผิดและวิธีการแก้ไขโดยเฉพาะอย่างยิ่งกับรหัสว่า "ฉันจะไม่ recomment ทำ 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();
หรือไม่? จะลบการแบนได้อย่างไร? ฉันไม่รู้.