我不确定我是否太累了,并且错过了一些事先道歉。
我有一个我需要重组的php域,因为结束了使用服务的贫血模型。这是因为我没有使用Doctrine而是使用Laravel的Eloquent作为我的映射器(原因是由于链接到其他不同的DB服务器类型)
我的审核结构需要与此类似:(我只是为此示例包含了一些内容)
模板实体将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 interface
return $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的更好方法吗?我不想从容器注入域名,但除非你使用不同的架构,否则不要认为有更好的方法。
答案 0 :(得分:0)
我认为你过于复杂了。
如果在非常通用的方法签名中使用规范模式,该规范将规范作为参数,或者如果您有一整套规范。只需要测试一两个特定条件,就可能有点过分了。
此外,尝试将存储库注入域对象(正如我猜你的那样)可能会给你带来更多麻烦而不是好处。字符串长度很可能不是域规则和唯一性may not be either。您可能最好在应用程序服务(或控制器)级别检查这些约束,直接在那里调用存储库以获得唯一性,这将为您节省所有注入问题。