1

I have a data model object User. My app also has some other data model objects, Fork and Options, for example. Users have forks and branches. My app has to run a lot of queries with some combination of User/Fork/Options etc. information. For example, you can see a page of User's Forks. This would require a query that joins that User (e.g. the logged in user in the session) on Forks.

I don't want to violate the Law of Demeter, and I am also typically against getters (and setters) in general, so I don't want to implement User::getID() or User::getUsername().

However, the alternative does not seem much better to me. What has ended up happening is that I implement various methods in User to run these queries (e.g. User::getForks()). In general this works, but the User class has become monolithic which is bad in its own way.

What's more is I'm not sure how I would resolve a query of two data model objects. For example, I could have a User with an id and a Fork with an id and want to check that the fork belongs to the user. This requires that either the Fork exposes its id to the user, the User exposes its id to the Fork, or both expose their ids to the controller (or whatever else). None of these seem desirable, and I'm not sure which to choose. Is there some other alternative that I'm missing?

In another similar step, I'm not sure of the best way to add information to the view. I have a view object, and typically I use a method like User::addForksToView(View $view), which will run a query or queries and do some processing, but this also increases the size and responsibility of User. I think this is a similar problem.

4

1 回答 1

1

而不是对象getForks中的方法User,使用 aForksFactory或类似的东西。工厂可以有 和 之类的fromUser(User $user)方法byId($id)。这样,User对象就没有对对象的隐藏依赖Fork,并且可能对数据库访问有隐藏的依赖。ForksFactory依赖于数据库并包含只需要获取数据和创建的代码,Forks这就是它知道如何做的全部。由于Fork对象不会依赖于数据库,而现在User对象不需要知道任何关于Fork的,确实Fork根本不存在并且User不在乎。这是单一用途对象的想法。

至于 getter 和 setter,为什么不公开像 id 和 name 这样的属性呢?或者,您可以使用魔术方法 __get__set控制哪些属性被视为只读,如果这是您所关心的。否则,您也可以公开这些属性——这是完全可以接受的。

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

于 2012-04-05T15:03:32.463 回答