存储库模式和共享实体

时间:2014-12-23 13:17:49

标签: php design-patterns architecture repository-pattern

我正在考虑使用存储库设计模式进行数据抽象,我正在使用Phalcon PHP框架并使用以下结构:

ModelA
    |- Entity
        |- Entity1.php
        |- Entity2.php
        |- Entity3.php
    |- Repository
        |- RepositoryA.php
    |- Service
        |- ServiceA.php

现在,如果我必须在另一个ModelB中使用相同的Entity2.php,我将失去对存储库模式的最方便的使用,即我只能通过修改RepositoryA来更改Entity2.php的数据源。 PHP,而不是担心谁也可能使用该实体。 如果我不允许直接访问实体,我就无法跨多个存储库执行连接。

处理此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

从您的描述中,我将假设ModelA / Repository / RepositoryA.php是一个具体的实现。 如果我正确理解您的问题,您还希望拥有ModelB / Repository / RepositorA.php,它们都访问相同的数据库表以提供相同的实体(例如,ModelA / Entity / EntityA.php)。

您可以做的一件事是将这两个RepositoryA类转换为接口,然后使用一个具体的类在其他地方实现,如下所示:

ModelA
    |- Entity
        |- Entity1.php
        |- Entity2.php
        |- Entity3.php
    |- Repository
        |- RepositoryA.php (interface, for dealing with ModelA\Entity\Entity1)
    |- Service
        |- ServiceA.php (depends on ModelA\Repository\RepositoryA)
ModelB
    |- Repository
        |- RepositoryB.php (interface, for dealing with ModelA\Entity\Entity1)
    |- Service
        |- ServiceB.php (depends on ModelB\Repository\RepositoryB)
Infrastructure
    |- Repository
        |- ConcreteEntity1Repository (concrete class that implements both RepositoryA and RepositoryB interfaces.  Somehow, an instance of this is passed to both ServiceA and ServiceB (dependancy injection or whatever you like))

通过这种方式,您可以将您正在使用的具体实现与服务层分开,从而在您需要时更灵活地更改内容。 (作为一个额外的好处,这将使得更容易进行单元测试代码等事情。)

使用这种方法,您可以在两个模型中有效地使用相同的存储库,但不会在它们之间创建任何耦合。根据您的系统架构,以这种方式进行设置可能相当复杂,而且对于这种情况可能有点过分。

另一种方法可能是不要将RepositoryA和RepositoryB作为接口,而是将它们转换为委派其工作的具体类,或者通过向它们传递一个公共的“Entity1Repository”(并让RepositoryA和RepositoryB包装它们需要的调用) ,或者通过创建一个它们都扩展的抽象基类,包含任何常用功能。

这样做的另一个好处是,您还可以添加特定于一个模型的内容,而不是其他模型的一部分。 (例如,ModelA \ Repository \ RepositoryA可以有一个函数findRelatedTo(Entity3 $ entity3),而不强制ModelB知道实体3是什么。)

答案 1 :(得分:0)

我对我的一个项目有类似的要求。我创建了一个基类,存储库可以像Jory Geert的解决方案一样扩展。这是我使用Phalcon 2.0和Doctrine 2创建的a sample starter project。实现不是那么干净,文档仍在进行中,但它应该给你一个想法。