例如:
我有一个有10个小部件的用户。除此之外,我还有一个管理其中5个小部件的管理器。
我想检索由指定Manager管理的用户窗口小部件。所以我在我的WidgetMapper中创建了一个名为fetchUsersManagedWidgets($ userId,$ managerId)的函数,它向db查询这5个小部件并映射Widget对象数组。
我知道域对象不应该知道它们的映射器,但是我可以在User模型中创建一个函数来调用WidgetMapper的函数吗?
e.g。
class Application_Model_User {
public function getWidgetsManagedBy($manager) {
$widgetMapper = new Application_Model_WidgetMapper;
return $widgetMapper->fetchUsersManagedWidgets($this->getId(), $manager->getId());
}
}
或者这是一条单行道,域对象永远不应该调用mapper函数吗?
答案 0 :(得分:1)
模式一般是如何解决常见问题的想法。他们不是“必须这样做”或“其他一切都不好”。实际上甚至a name对于不遵循故意模式的决定也是如此
从我所看到的人们倾向于认为“一个db-table是一个域,所以每个db-table需要一个模型和一个mapper”。在你的情况下,我想你有三个表:用户,小部件和这两个表之间保持n:m关系的表(我称之为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;
}
}
如果你不想使用默认的widget-mapper,你应该在访问用户的小部件之前设置它(它们应该按需加载)。