将Demeter定律与模型相协调

时间:2012-04-05 14:39:59

标签: php mysql model-view-controller law-of-demeter

我有一个数据模型对象User。我的应用程序还有一些其他数据模型对象,例如ForkOptions。用户有叉子和分支机构。我的应用程序必须使用User / Fork / Options等信息的一些组合运行大量查询。例如,您可以看到User's Forks页面。这将需要在Forks上连接该用户的查询(例如,会话中的登录用户)。

我不想违反Demeter法,我通常也反对getter(和setter),所以我不想实现User::getID()User::getUsername()。< / p>

然而,替代方案对我来说似乎并没有那么好。最终发生的事情是我在User中实施了各种方法来运行这些查询(例如User::getForks())。一般情况下这是有效的,但是User类已经变得单一,这本身就很糟糕。

更重要的是,我不确定如何解析两个数据模型对象的查询。例如,我可以拥有一个带有id的User和一个带有id的Fork,并且想要检查fork是否属于用户。这要求Fork向用户公开其id,User将其id公开给Fork,或者两者都将其ID暴露给控制器(或其他任何东西)。这些似乎都不可取,我不确定选择哪一个。还有其他一些我缺少的选择吗?

在另一个类似的步骤中,我不确定向视图添加信息的最佳方法。我有一个视图对象,通常我使用像User::addForksToView(View $view)这样的方法,它会运行查询或查询并进行一些处理,但这也会增加User的大小和责任。我认为这是一个类似的问题。

1 个答案:

答案 0 :(得分:1)

而不是getForks对象中的User方法,请使用ForksFactory或类似的内容。工厂可以使用fromUser(User $user)byId($id)等方法。这样User对象在Fork对象上没有hidden dependency,并且可能是对数据库访问的隐藏依赖。 ForksFactory依赖于数据库,并且包含仅获取数据并创建Forks所需的代码,这就是它知道该怎么做。由于Fork对象不具有数据库的依赖性,现在User对象不需要了解Fork的任何内容,实际上Fork确实不存在完全没有User无关紧要。这是一个单一用途对象的想法。

对于getter和setter,为什么不将id和name等属性公开为public?或者,您可以使用magic methods __get__set来控制哪些属性被视为只读,如果您担心的话。否则,您也可以公开属性 - 这是完全可以接受的。

你提到的其他代码听起来像是遭受同样的问题 - 一个对象,一个目的。理论上,每个对象都应该孤立存在,或者在构造函数中注入任何依赖关系。您的对象不应要求定义另一个对象,否则其中一个方法将失败。