Ich habe seit Tagen über DDD gelesen und brauche Hilfe bei diesem Beispieldesign. Alle DDD-Regeln verwirren mich sehr, wie ich überhaupt etwas erstellen soll, wenn Domänenobjekte der Anwendungsebene keine Methoden anzeigen dürfen. Wo sonst kann man Verhalten orchestrieren? Repositorys dürfen nicht in Entitäten injiziert werden, und die Entitäten selbst müssen daher am Status arbeiten. Dann muss eine Entität etwas anderes aus der Domäne wissen, aber andere Entitätsobjekte dürfen auch nicht injiziert werden. Einige dieser Dinge ergeben für mich einen Sinn, andere nicht. Ich habe noch keine guten Beispiele dafür gefunden, wie man ein ganzes Feature erstellt, da es in jedem Beispiel um Bestellungen und Produkte geht und die anderen Beispiele immer wieder wiederholt werden. Ich lerne am besten anhand von Beispielen und habe versucht, anhand der Informationen, die ich bisher über DDD erhalten habe, ein Feature zu erstellen.
Ich brauche Ihre Hilfe, um darauf hinzuweisen, was ich falsch mache und wie ich es beheben kann. Am besten mit Code, da "Ich würde es nicht empfehlen, X und Y zu machen" in einem Kontext, in dem alles nur vage definiert ist, sehr schwer zu verstehen ist. Wenn ich eine Entität nicht in eine andere injizieren kann, ist es einfacher zu sehen, wie es richtig gemacht wird.
In meinem Beispiel gibt es Benutzer und Moderatoren. Ein Moderator kann Benutzer sperren, jedoch mit einer Geschäftsregel: nur 3 pro Tag. Ich habe versucht, ein Klassendiagramm zu erstellen, um die Beziehungen anzuzeigen (Code unten):

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);
Sollte die Benutzerberechtigung ein 'is_banned'Feld haben, mit dem geprüft werden kann $user->isBanned();? Wie hebe ich ein Verbot auf? Ich habe keine Ahnung.