【问题标题】:Repository pattern and shared entities存储库模式和共享实体
【发布时间】:2015-02-21 15:28:48
【问题描述】:

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

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

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

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

【问题讨论】:

  • 为什么你认为你会失去对存储库模式最方便的使用

标签: php design-patterns architecture repository-pattern


【解决方案1】:

根据您的描述,我将假设 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 知道 Entity3 是什么。)

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 2022-08-19
      • 2014-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多