一个对象什么时候应该作为另一个对象的成员包含在内,什么时候它应该始终独立?

发布于 2024-10-23 18:15:26 字数 968 浏览 5 评论 0 原文

一个示例问题:

在 Stack Overflow 上,问题页面显示了许多不同的答案。在显示这些答案时,该网站还提供有关答案作者的信息。这意味着,尽管给定用户拥有的徽章数量与答案本身无关,但仍然需要检索该数据才能显示页面。

据我所知,可以通过三种不同的方法在模型中提取此视图数据:

  1. Post 对象可以包含完整的 User 对象作为成员。然后视图将像这样访问用户:$post->user->getReputation()。这看起来更干净,因为控制器可以只请求帖子并完成它,但效率很低,因为帖子可能并不总是需要成熟的用户。我想如果用户对象相对较轻(它可能会是这样),它就足够好了。那么问题就在于您需要复制 User 检索代码作为 Post 检索查询的一部分。

  2. Post 对象只能保存用户的 ID。当一个或多个帖子返回到控制器时,控制器可以从返回的集合中提取唯一的用户 ID,并将它们传递给用户工厂。然后,返回的 User 对象将与设置为单独集合的 View 的原始 Posts 一起传递。然后,视图可以使用诸如 $users[$post->getUserId()]->getReputation() 之类的内容来获取用户信息。

  3. 混合方法:将 User 对象包含在 Post 对象内,但将唯一 id 提取和 User 检索作为 Post 检索方法的一部分。即 Post::getPosts() 会抓取所有相关帖子并将它们转换为具有 null User 成员的对象,然后提取所有用户 ID 并将它们传递给 User::getUsers() ,然后将用户分配给相关帖子,然后将帖子集返回给调用者。

我想我的意思是,我如何知道一个对象何时需要从根本上包含另一个对象?单独返回此类相关对象是否不干净/有代码味道,两个对象都不知道另一个对象已被检索。我倾向于单独的检索概念——它似乎是最有效的——但确实感觉它们太相关了,以至于没有意义。

An example problem:

On Stack Overflow, a question page shows a number of different answers. In displaying these answers, the site also gives information about the author of the answer. This means that although the number of badges a given user has has nothing to do with an answer in and of itself, that data still needs to be retrieved in order to display the page.

From what I can see, there are three different ways to go about pulling this view data in a model:

  1. A Post object could include a full User object as a member. The view would then access the user like this: $post->user->getReputation(). This seems cleaner, since a Controller could just request the posts and be done with it, but yet inefficient since a Post probably doesn't always need a full-blown User. I suppose it works well enough if the User object is relatively light, which it probably would be. The problem would then be that you would need to duplicate User retrieval code as part of the Post retrieval query.

  2. The Post object could hold just an ID for a User. When the Post, or Posts, are returned to the Controller, the Controller could then extract the unique User IDs from the returned set and pass them to a User factory. The returned User objects would then be passed along with the original Posts set to the View as a separate collection. The view could then grab user info using something like $users[$post->getUserId()]->getReputation().

  3. A hybrid approach: Include the User object inside the Post object, but have the unique id extraction and User retrieval as part of the Post retrieval method. i.e. Post::getPosts() would grab all relevant posts and convert them to objects with null User members, then it'd extract all user ids and pass them to User::getUsers(), then assign the Users to the relevant Posts before returning the set of Posts to the caller.

I guess what I'm getting at is, how do I know when an object needs to contain another object fundamentally? Is it unclean/a code smell to instead have such related objects returned separately, with neither object knowing the other has been retrieved. I'm leaning towards the separate retrieval concept - it seems the most efficient - but it really does feel like they're too related for that to make sense.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

野味少女 2024-10-30 18:15:26

还有一种介于 1 和 2 之间的解决方案。您可以为用户类设置一个延迟加载代理。通过此解决方案,您可以两全其美,因为代理可以与真实事物互换,因此根据情况您可以拥有对象本身或代理。

编辑:
我将尝试用一个例子来解释这一点。

假设您有一个不需要用户信息的视图,那么您可以指示/配置您的帖子工厂以使用惰性代理(参见维基百科)了解仅包含 ID 的用户。因此不需要访问用户。

在另一个视图中,您偶尔需要访问用户信息,但仅限于某些帖子,在这里您再次指示/配置您的工厂以包含用户的惰性代理。
但是,当您实际需要访问用户信息时,您可以访问代理对象,然后该代理对象将加载实际的用户对象并将消息重定向到它。

在另一个视图中,您需要帖子和用户信息,因此在这里您指示帖子工厂使用实际的用户对象。

There is also a solution in between 1 and 2. You can have a lazy loading proxy for the user class. With this solution you can have best of both worlds because the proxy is interchangeable with the real thing so depending on the situation you can have the object itself or the proxy.

Edit:
I'll try to explain this with an example.

Say that you have a view where you don't need user info, then you can instruct/configure your post factory to use the lazy proxy (see wikipedia)for the user which will only contain an ID. So no access to users is needed.

In another view you occasionally need to access user info but only for some posts, here again you instruct/configure your factory to include the lazy proxy for the user.
But when you actually need access to the user info, you can access the proxy object that will then load the actual user object and redirect messages to it.

In yet another view you need both post and user info, so here you instruct your post factory to use actual user objects.

寂寞美少年 2024-10-30 18:15:26

在我看来,这是依赖注入的另一种情况。一个足够普遍的想法可以帮助你。

依赖注入 WIKI

还可以阅读有关控制反转的内容。

It seems to me that this is another case of dependency injection. A general enough idea that could help you.

DEPENDENCY INJECTION WIKI

Read something about the Inversion Of Control also.

罪歌 2024-10-30 18:15:26

为什么不向模型添加可选成员来了解信息?不需要的时候可以忽略,需要的时候可以使用。

why not add optional member to model to know informations?? you can ignore when you don't need and can use when you do need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文