Zend framework 域对象可以调用其他数据映射程序吗?(Zend框架)

Zend framework 域对象可以调用其他数据映射程序吗?(Zend框架),zend-framework,datamapper,domain-model,Zend Framework,Datamapper,Domain Model,例如: 我有一个用户有10个小部件。除此之外,我还有一个管理器来管理其中的5个小部件 我想检索由指定管理器管理的用户小部件。因此,我在WidgetMapper中创建了一个名为fetchUsersManagedWidgets($userId,$managerId)的函数,该函数在db中查询这5个小部件,并映射一组小部件对象 我知道域对象不应该知道它们的映射器,但是我可以在用户模型中创建一个调用WidgetMapper函数的函数吗 e、 g 或者这是一条单行道,域对象永远不应该调用映射器函数?模式通

例如:

我有一个用户有10个小部件。除此之外,我还有一个管理器来管理其中的5个小部件

我想检索由指定管理器管理的用户小部件。因此,我在WidgetMapper中创建了一个名为fetchUsersManagedWidgets($userId,$managerId)的函数,该函数在db中查询这5个小部件,并映射一组小部件对象

我知道域对象不应该知道它们的映射器,但是我可以在用户模型中创建一个调用WidgetMapper函数的函数吗

e、 g


或者这是一条单行道,域对象永远不应该调用映射器函数?

模式通常是解决常见问题的方法。他们既不是“必须那样做”也不是“其他一切都不好”。事实上,甚至还有一种决断不是有意遵循模式的。
从我所看到的情况来看,人们倾向于认为“一个db表就是一个域,所以每个db表都需要一个模型和一个映射器”。在您的例子中,我假设您有三个表:用户、小部件和保存这两个表之间的n:m关系的表(我称之为userwidgets)。
userwidgets实际上是用户模型的一部分,没有自己的模型/映射器,并且不是widget模型的一部分。要解决usermodel中的这些小部件ID,当然需要小部件映射器,这会导致您描述的问题。
可能有很多方法可以解决这个问题,我只是假设一个默认的映射器是可覆盖的:

Class UserModel
{
    $_widgetMapper = null;

    public function getWidgetMapper()
    {
        if(null === $this->_widgetMapper)
        {
             $this->setWidgetMapper(new DefaultWidgetMapper());
        }
        return $this->_widgetMapper();
    }

    public function setWidgetMapper($mapper)
    {
        // todo: make sure it's a mapper of the correct type
        $this->_widgetMapper = $mapper;
    }
}

如果您不想使用默认的小部件映射器,您只需在访问用户的小部件之前设置它(它们应按需加载)。

您说得对,我有一个具有n:m关系的UserWidgets表。这就引出了一个后续问题。如果userwidgets没有自己的模型/映射器,我应该使用哪个映射器将关系保存到db?我想说用户映射器中一个名为saveUserWidgets($user,$widgets)的函数是否正确?@craig:是的,我首先要将它添加到用户映射器中。从widgetMapper pov中,我将是一个函数addUser($widget,$user)。两者都可以做到,两者都是正确的,两者都可能有用。我会坚持使用saveUserWidget(或者甚至是atomar,比如addWidget($User,$widget)和removeWidget(…),这取决于您的操作。只要您知道它们在做什么,这里就允许使用每个函数;)映射器没有“禁止”或“必须具有功能”。
Class UserModel
{
    $_widgetMapper = null;

    public function getWidgetMapper()
    {
        if(null === $this->_widgetMapper)
        {
             $this->setWidgetMapper(new DefaultWidgetMapper());
        }
        return $this->_widgetMapper();
    }

    public function setWidgetMapper($mapper)
    {
        // todo: make sure it's a mapper of the correct type
        $this->_widgetMapper = $mapper;
    }
}