4

一个 ZF2 系统中有许多组件。每个组件都有自己的表示层、业务层和数据层。问题是当组件 Foo 有一个使用组件 Bar 的数据层的控制器时。

例子:

<inside modules, each module can be individually deployed or removed>
\modules
   \Foo                  ; one module (this directory) can be added or removed
     \view               ; presentation layer (view) for all subcomponents
        \Subcomponent1
            \Action1
        \Subcomponent2
            \Action2
        ...
     \src
        \Subcomponent1
            \Entity      ; data layer     (model)
            \Controller  ; business layer (controller)
            \Service     ; service layer  (service)
        \Subcomponent2
            \Entity
            \Controller
            \Service
        \Subcomponent3
            ...
  \Bar
     \view
         ...
     \src
         \Subcomponent1
            ...
  \Baz
     \src
         \Subcomponent1
            ...

子组件与来自其他子组件的实体强耦合,通常来自完全不同的组件。控制器和服务就是这种情况。这可以解决吗?

Foo\Subcomponent1 有一个 FooSub1Service,它使用 Bar\Subcomponent1 中的实体来处理传递的数据并将它们导入数据库。Baz\Subcomponent1 有一个 AuthenticationService,它使用 Bar\Subcomponent1 实体通过 ID 等查找用户。

我知道依赖注入,但在这种情况下,每个子组件中都有 EntityManager,它被指示按名称和 PK 查找实体,即 find("Bar\Subcomponent1\Entity\User", 123)。而且,在持久化实体时,我必须实例化任何具有外键的东西,即 UserAddress 并将其添加到 User。每次我调用 x = new NameOfEntity() 时,我都会将子组件与子组件中的某个实体紧密耦合,通常来自不同的系统模块。

4

3 回答 3

7

在 ZF2 中,可以使用 减少模块之间的耦合EventManager,另请参见此处

此外,module/config/module.config.php用作Facade

所有实体都可以在任何模块的文件中定义一次。module/config/module.config.php然后其他模块可以使用ServiceManager来解决它们的依赖关系。

ServiceManager实现了服务定位器模式

使用 Facade ( module.config.php) 和EventManager,成功地减少了模块之间的耦合。

于 2012-11-26T09:48:13.500 回答
0

您不能总是删除所有依赖项。例如,身份验证模块通常依赖于某种形式的用户凭据。

减少与特定类耦合的一种方法是允许使用适配器替换依赖项。

例如,如果您希望能够在身份验证模块中使用不同类型的用户模块,您可以在身份验证模块中定义一个接口,该接口必须由用户模块中的适配器实现,以便与它。然后,向您的 auth 模块添加一个配置选项,该选项允许用户更改使用的用户适配器实现。

根据复杂性,您还可以简单地为对象本身定义特定接口,而不是使用适配器。但是,这有时可能会在对象中添加不相关的功能等,可能会使它们的实现更难理解。

最后,我建议不要尝试在您的代码中实现过多的灵活性。除非您计划与世界共享您的模块,否则您不太可能需要它,因为只需更改模块中具有硬依赖的几行代码通常会简单得多,而不是编写全新的接口和类. 这显然是您需要根据您计划如何使用这些模块来评估自己的事情。

于 2012-11-25T18:53:33.153 回答
0

不要直接访问实体或存储库。每个模块实现一个或多个服务,你可以给他们一个接口来清楚地说明这一点。

如果您像 ORM Doctrine 2 一样使用数据层,那么每个模块中的每个 /entity 文件夹无论如何都是共享的。这使得可以在一个存储库中进行连接并获取连接的实体。这还不错。

不要仅仅为了减少依赖而滥用事件管理器。使用共享服务并仅使用这些服务。

当您想要调用整个应用程序并收集东西或需要答案时,请使用事件管理器。

于 2014-11-27T17:37:07.480 回答