не уверен, что я просто слишком устал и что-то пропустил, поэтому заранее извиняюсь.
У меня есть домен php, который мне нужно реструктурировать, потому что закончилась анемичная модель с использованием сервисов. Это потому, что я не использую Doctrine, но Eloquent от Laravel в качестве моего картографа (причины связаны с ссылками на другие типы серверов БД)
Моя проверенная структура должна быть чем-то похожим, чтобы сделать это: (Я включаю только пару вещей для этого примера)
Шаблонный объект имеет TemplateName как VO.
TemplateName должно удовлетворять 2 спецификациям. Должен быть длиной более 3 символов и должен быть уникальным.
Я использую TemplateRepositoryInterface для проверки уникальности, и интерфейс имеет реализацию Eloquent, ограниченную поставщиком услуг.
Следовательно, у сущности шаблона есть метод:
public function create()
{
if ($this->meetsTemplateNameSpecification())
{
//fire events etc... saving to repo is done one step above from a service that call this class and gets $this to send tot he interfacereturn $this;
}
throw new InvalidArgumentException("Template name is not valid.");
}
Тогда мой метод meetTemplateNameSpecification:
private function meetsTemplateNameSpecification($originalTemplateName = null)
{
$templateNameSpecification = new TemplateNameSpecification($this->name, $originalTemplateName);
if($templateNameSpecification->isMet())
{
return true;
}
return false;
}
До этой реструктуризации служба инициировала все это и передавала им RepositoryInterface, чтобы это было легко. Тем не менее, таким образом, я не знаю, как и / или где передать или внедрить интерфейс, потому что, если он будет вставлен из контейнера в класс Specification, я не смогу инициировать его из Entity и не смогу внедрить класс Spec в объект либо потому, что я хочу иметь возможность использовать его конструктор.
Я нахожу, что в PHP и Active Record очень сложно сделать разделение проблем и не зависеть от постоянства в домене.
У кого-нибудь есть лучшая структура? Дайте мне знать, если вам нужно больше кода, пожалуйста.
Пока единственное решение, которое приходит на ум, — это иметь статические методы в моих объектах спецификации, чтобы их не нужно было инициировать, и я могу внедрить зависимость Repo из контейнера. Это путь или есть лучшие способы работы с PHP. Я ненавижу вводить из контейнера в домен тоже, но не думаю, что есть лучший способ, если вы не используете другую архитектуру.
Я думаю, вы слишком усложняете вещи.
Шаблон спецификации хорош, если используется в очень общей сигнатуре метода, которая принимает спецификации в качестве параметров, или если у вас есть целое семейство спецификаций. С одним или двумя конкретными условиями для тестирования, это может быть излишним.
Кроме того, попытка внедрить репозиторий в объект домена (как я полагаю, вы) может принести вам больше проблем, чем пользы. Длина строки, скорее всего, не является правилом домена и уникальностью может и не быть. Возможно, вам лучше проверить эти ограничения на уровне службы приложений (или контроллера), напрямую вызвав хранилище для уникальности, что избавит вас от всех проблем с внедрением.
Других решений пока нет …