【问题标题】:When an objectA wants to send a message to objectB, where should the method live?当一个对象想要向对象发送消息时,该方法应该放在哪里?
【发布时间】:2016-02-20 03:59:05
【问题描述】:

假设您创建了两个对象:objectA 和 objecB。如果 objectA 需要向 objectB 发送消息,应该是这样的:

objectA.theMessage(objectB)

或者像这样:

objectB.theMessage(objectA)

一个更具体的例子:

Publisher p;
Subscriber s;

// way 1
p.addSubscriber(s);

// way 2
s.subscribeTo(p);

正如你所看到的,两个消息(函数)的语义是相同的,只是函数应该放在哪里的问题。

是否有硬性规定规定应该做什么?或者是否有一个通用指南可以帮助您确定哪个是更好的设计?或者这是逐案处理并且不存在一般准则?如果是这样,你能解释一下我什么时候会使用它们。您能想到每种方法的潜在优势/劣势吗?

非常感谢您的时间和知识!

【问题讨论】:

  • 如果你添加了一个特定于语言的标签,你会在这个问题上得到更多的关注,但是你正在寻找的是所谓的观察者模式
  • 感谢您关于添加语言标签的建议! :) 我知道观察者模式,这就是我使用发布者/订阅者示例的原因:) 哈哈。我要问的是:关于消息应该放在哪里,是否有一般规则(不限于观察者模式)?他们应该住在哪个对象中? :)

标签: java c++ extensibility maintainability


【解决方案1】:

这里的区别在于您更喜欢推式还是拉式模式。哪个更适合在很大程度上取决于应用程序。 “推送”基本上意味着A 发送B 消息,而“拉”意味着BA 获取消息。

如前所述,没有一般规则,但通常可以用常识回答问题。举个例子:今天早上我和我的家人吃了早餐。以前,我不得不开车去面包店买一些面包(它在德国,我们喜欢我们的 Brötchen)。另一方面,我早餐时阅读的报纸来自送纸员。这个设置是合适的:是我想要面包包,所以我做了一些工作才能得到它们,但我可能会懒得出去买报纸(除非可以在面包店买到)。另一方面,如果面包包子已经送达而报纸没有送达,我最终会得到更贵的包子而没有报纸。愚蠢的例子结束。

那么,这对您的设计意味着什么?必然需要将消息从A 发送到B 的人会触发它。根据我的经验,这通常是接收者,这就是为什么拉模式通常是首选的原因(而且,它更容易延迟评估——只在真正需要时才获取消息)。但如前所述,这实际上取决于应用程序。做出你的选择:-)

【讨论】:

  • 我认为当一个对象想知道另一个对象发生了什么事情时,使用了推/拉方法?例如,如果我们有一个 Timer 对象和一个 Person 对象,该人想知道计时器是否已启动,push 会建议 Timer 在启动时告诉 Person,而 pull 会建议 Person ASK the timer “你有吗?开始了吗?”定期。在我在我的问题中使用的示例中(订阅者订阅发布者),您更愿意这样做:publisher.addSubscriber(subscriber) 还是subscriber.subscribeTo(publisher)?
  • ...继续...“将订阅者添加到推送器”的责任应该在哪里?我“感觉”它应该在发布者中,但是我也“感觉”如果我让客户做任何一个,它都会为他们提供更多的灵活性。但是我必须确保代码只在一个类中(另一个只是委托)。在这种情况下,您需要其中一个类可以访问另一个类的私有(呵呵),这会减少封装吗?那么为客户端增加的灵活性是否值得更强的耦合和减少的封装?
  • @MeLikeyCode:您对推/拉的想法与我在答案中写的相同。简而言之:“推送”:A 推送到 B。 “拉”:BA 拉。订阅问题的常用方法如您所说:A 提供“subscribeWithMe”,B 必须自行调用它......但请注意,这对应于推送模式。使用拉模式,A 原则上根本不需要知道B ...但当然B 必须知道A(即用A 构造,或者提供方法@987654339 @ ETC。)。除非你有一个固定的信息流,否则你不会得到它/wo 用户操作。
  • 感谢您的澄清!我猜推/拉概念比观察者模式更普遍! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多