1

Lets say you create two objects: objectA and objecB. If objectA needs to send a message to objectB should it happen like this:

objectA.theMessage(objectB)

or like this:

objectB.theMessage(objectA)

A more concrete example:

Publisher p;
Subscriber s;

// way 1
p.addSubscriber(s);

// way 2
s.subscribeTo(p);

As you can see, the semantics of both messeges (functions) are the same, its just a matter of where the function should live in.

Is there a hard and fast rule that states which should be done? Or Is there a general guideline that helps you in determining which is the better design? Or Is this a case by case thing and no general guideline exists? If so, could you explain when I would use each. Can you think of any potential advantages/disadvantages of each?

Thank you very much for your time and knowledge!

MeLikeyCode
  • 297
  • 4
  • 13
  • 1
    You would get more attention on this question if you added a language-specific tag, but what you are looking for is called the Observer Pattern – OneCricketeer Feb 20 '16 at 04:03
  • Thank you for the advice about adding a language tag! :) I know about the observer pattern, thats why I used the publisher/subscriber example :) haha. What I am asking about is: is there a general rule (not limited to the observer pattern) as to where messages should live? In which object should they live? :) – MeLikeyCode Feb 20 '16 at 04:13

1 Answers1

2

The difference here is whether you prefer the push or the pull pattern. Which one is better suited heavily depends on the application. "Push" basically means A sends B the message, whereas "pull" means B fetches the mesage from A.

As said, there is no general rule, but often one can answer the question with common sense. Consider an example: this morning my family and I had breakfast. Before, I had to drive to the bakery in order to get some bread buns (it's in Germany, we like our Brötchen). On the other hand, the newspaper I read at breakfast came from a paper deliverer. This setup is appropriate: it's me who wanted the bread buns so I did some work in order to get them, but I would have probably been to lazy to go out and buy a newspaper (unless it can be obtained at the baker). On the other hand, if the bread buns would have been delivered and the newspaper not, I would end up with more expensive buns and no newspaper. Silly example end.

So, what does that mean for your design? The one who necessarily needs the message been sent from A to B triggers it. In my experience, this is often the receiver, which is why the pull pattern is often the first choice (also, it allows more easily for lazy evaluation -- only get the message when it's really needed). But as said, it really depends on the application. Make your choice :-)

davidhigh
  • 14,652
  • 2
  • 44
  • 75
  • I thought the push/pull method was used when one object wants to know when something has happened to another object? For example If we have a Timer object and a Person object, the person wants to know if the timer has started, push would suggest the Timer TELLS the Person when it has started, where as pull would suggest the Person ASK the timer "have you started yet?" periodically. In the example that I used in my question (a subscriber subscribing to a publisher), which would you rather do: publisher.addSubscriber(subscriber) or subscriber.subscribeTo(publisher)? – MeLikeyCode Feb 20 '16 at 17:34
  • ...continued...Where should the responsibility of "adding a subscriber to a puslisher" be in? I "feel" like it should be in the publisher, however I also "feel" like if I let clients do either, it would offer them more flexibility. But then I would have to ensure that the code is in only one class (the other simply delegating). In this case, you would need one of the classes to have access to the privates (hehe) of the other class, which reduces encapsulation? So is the added flexibility to the client worth the stronger coupling and reduced encapsulation? – MeLikeyCode Feb 20 '16 at 17:35
  • 1
    @MeLikeyCode: your thoughts regarding push/pull just equal what I wrote in the answer. In short again: "Push": `A` pushes to `B`. "Pull": `B` pulls from `A`. The usual approach to the subscribing problem is as you said: `A` offers a "`subscribeWithMe`" and `B` has to call it with itself ... but note that this corresponds to a push pattern. Using a pull pattern, `A` in principle does not need to know `B` at all ...but of course `B` has to know `A` (i.e. be constructed with `A`, or provide a method `pullFrom(A *)` etc.). Unless you have a fixed information flow, you don't get it /wo user action. – davidhigh Feb 20 '16 at 19:49
  • Thank you for the clarification! I guess the push/pull concept is more general than just the observer pattern! :) – MeLikeyCode Feb 21 '16 at 00:12