让我设置场景:
我有一个“Item”类,它有不同的食物(如胡萝卜,苹果等)。 这链接到“项目”表。一切都很好。
在我迁移的旧框架中,我还有一个“Complete Protein”类,它在构造函数中需要一个Item对象。这个“CompleteProtein”对象将能够执行复杂的查询和方法,并包含有关“完整蛋白质”的一般信息。
这适合Laravel?它似乎不是一个雄辩的模型,因为它不直接与数据库中的任何表相关,但它确实进行数据库查询。它确实有依赖注入(Item),以及类中的复杂方法和常量。
我应该以某种方式使这些适合“Item”类吗?我觉得那会很混乱。
答案 0 :(得分:5)
你真的不需要Eloquent模型。我甚至不使用Eloquent(但绝对喜欢Laravel的其余部分)。我甚至不使用ORM(甚至不是Doctrine2)。但是,如果您仍然喜欢使用它,请将其视为您的基础架构的一部分,而不是您的业务领域的一部分。在Repository methods findByEmail()
或save()
内进行Eloquent调用。许多人将存储库作为一个接口,因此他们可以交换服务提供程序中的实现进行测试(在这里使用内存存储库实现,可能只是将数据存储在数组中)。同样,我不会从这些存储库中返回Eloquent Models,而是返回水合域对象。
您所描述的是您商家域中的实体。这可能是您的业务领域中的域服务,但听起来更像是一个实体(在DDD中)。我会将该实体放在类似这样的位置的类中:
app\
Domain\
CompleteProteins\
CompleteProtein.php
CompleteProteinRepository.php
Items\
Item.php
ItemRepository.php
(maybe some domain service classes here as well)
Http\
Queries\
Helpers\
Services\ (<-- maybe application level services here)
etc...
现在,在您的CompleteProtein.php
中编写一个具有所需属性的类,并为其提供方法(因此它为not anemic),以形成代表业务中明确定义的“事物”的实体。将“收集”所需的方法分开,如操作。这些是您从数据库中获取并持久化为数据库之类的操作。分离出这些特殊方法并将它们放入Repository中。您的代码最终将如下所示:
$protein = new CompleteProtein($item, $blah, $blahblah);
$protein->doSomethingWith("Apples");
$proteinRepository->persist($protein);
这是编写和封装规则的好方法。新开发人员很容易看到构成您业务的所有“事物”。如果您的开发人员希望做一些持久性,那么您可以指示他/她“去存储库”。这里和那里都没有一次性的询问!没有任何ORM调用(假装您的关系数据库是OO)!您还可以在域对象上使用方法,例如markAsDeleted
(或者更好的是markAsErroneous
),这样当您使用->persist
将其发送到存储库时,存储库可以查找标记你的对象并知道删除它。这允许您向删除添加逻辑。研究使用PHP的Reflection类的技术,使存储库能够访问水合物/脱水域对象。 Zend框架有一个我喜欢使用的基本框架。存储库也适用于类似大规模集合的计算。
(注意:我在上面列出了一个名为Queries
的文件夹,您可以为READ查询情况创建类。在很多情况下,您不需要在您的存储库中保存完整的实体。只想在整个应用程序中在屏幕上显示信息.Google“Command Query Separation”。)
答案 1 :(得分:0)
这是一个服务类。无论您选择哪种框架,我都会将其命名为。
有些人更喜欢名为“服务”的文件夹(和命名空间),其他人更喜欢使用静音域驱动的方法(也许是一个名为“蛋白质”的文件夹来保存它?)但这取决于你。