Прошло много времени с тех пор, как я начал создавать свое приложение DDD / Hexagonal Architecture, и меня охватило множество концепций, связанных с ними обоими.
Хотя я начал немного ходить и пытаться применять концепции, когда я нашел их необходимыми. Я нахожу, что есть еще многие из них, которые я не могу или даже не думаю о применении в моем приложении, некоторые из них: Адаптеры, Команды (CQRS?), События ..
Кроме того, я немного застрял в чем-то, что связано с шестиугольной архитектурой.
Я пытаюсь применить определение внешнего поведения, должно зависеть вовнутрь, поэтому Уровень инфраструктуры -> Уровень приложения -> Уровень домена
В моем случае я определил Сервисы в моем Уровень приложений как этот пример LoginService:
class LoginUserService implements ApplicationServiceInterface
{
private $userRepository;
private $session;
public function __construct(UserRepositoryInterface $userRepository, Session $session)
{
$this->userRepository = $userRepository;
$this->session = $session;
}
public function execute($request = null)
{
// TODO: Implement execute() method.
$userName = $request->get('user');
$password = $request->get('password');
$user = $this->userRepository->findByUsername($userName);
if (!empty($user) && $user->validate($password)) {
$this->session->start();
$this->session->set('user', array('id' => $user->getUserId(), 'username' => $user->getName(), 'email' => $user->getEmail()));
return true;
} else {
return false;
}
}
}
Но я совершенно уверен, что я взрываю выражение зависимости, обозначающее гексагональную архитектуру. Так как мой уровень приложений зависит от уровня инфраструктуры.
(В этом случае, $this->userRepository->findByUsername($userName);
является частью DoctrineUserRepository, внедренной в serviceContainer приложения)
Мой репозиторий полностью доступен в github: Malendar Repository
Как бороться с этим случаем обслуживания, который зависит от выходных данных базы данных?
Кроме того, какие концепции я пропускаю, и это было бы неплохо использовать?
Заранее спасибо = D
UserRepositoryInterface
должны быть определены на уровне домена. Если он находится на уровне инфраструктуры, вы должны переместить его на уровень домена.
Когда вы создали UserRepositoryInterface
, вы создали контракт, который должны выполняться всеми реализациями уровня инфраструктуры. Это пример из учебника Принцип обращения зависимостей.
Вы можете смело предполагать, что реализации выполняют контракт. Это предположение не создать зависимость от уровня инфраструктуры.
Так, LoginUserService
зависит только от UserRepositoryInterface
(который должен быть частью уровня домена) и Session
,
Я бы больше беспокоился о Session
зависимость и тому $request
параметр. Я не знаю PHP и фреймворка, который вы используете, но в паттерне MVC я бы предпочел оставить оба в контроллере, делегируя логику на прикладном уровне. Практическое правило заключается в том, что прикладной уровень не должен отвечать за решение каких-либо проблем, связанных с HTTP. Я бы сделал LoginUserService.execute
метод принять $userName
а также $password
параметры и вернуть данные пользователя.
Это, конечно, сломает implements ApplicationServiceInterface
часть, но этот интерфейс должен быть удален в любом случае. Методы уровня приложения будут иметь разные параметры и типы возвращаемых данных.
Других решений пока нет …