我有一个数据模型对象User
。我的应用程序还有一些其他数据模型对象,例如Fork
和Options
。用户有叉子和分支机构。我的应用程序必须使用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
的大小和责任。我认为这是一个类似的问题。
答案 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
来控制哪些属性被视为只读,如果您担心的话。否则,您也可以公开属性 - 这是完全可以接受的。
你提到的其他代码听起来像是遭受同样的问题 - 一个对象,一个目的。理论上,每个对象都应该孤立存在,或者在构造函数中注入任何依赖关系。您的对象不应要求定义另一个对象,否则其中一个方法将失败。