2

例如:

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

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

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

例如

class Application_Model_User {

    public function getWidgetsManagedBy($manager) {
        $widgetMapper = new Application_Model_WidgetMapper;
        return $widgetMapper->fetchUsersManagedWidgets($this->getId(), $manager->getId());
    }

}

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

4

1 回答 1

1

一般来说,模式是关于如何解决常见问题的想法。他们既不是“必须那样做”或“其他一切都不好”。事实上,甚至有一个名称可以用来表示不有意遵循模式的决策。
据我所见,人们倾向于认为“一个 db-table 是一个域,因此每个 db-table 都需要一个模型和一个映射器”。在您的情况下,我假设您有三个表:用户、小部件和保存这两者之间的 n:m 关系的表(我将其称为 userwidgets)。
userwidgets 实际上是用户模型的一部分,没有自己的模型/映射器,也不是小部件模型的一部分。要解决用户模型中的那些小部件 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;
    }
}

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

于 2010-11-19T17:31:08.533 回答