12

I was wondering about the following implementation of

public void update(Observable obs, Object arg)

while I want to send to all of my observer and update using notifyObserver() I and passing a references to this the observer can use the getters from the subject to pull the information he wants.

What is the arg argument on the update method meant for?

1
  • @RBT arg is a parameter or group of parameters, as an additional option
    – umlcat
    Commented Apr 2, 2020 at 16:53

1 Answer 1

13

When implementing the Observer pattern, there are two main approaches to consider: the 'push' model and the 'pull' model.

In the 'push' model, the subject (i.e. the Observable) sends the observer on notification all the data it will need. The observer doesn't need to query the subject for information. In the 'pull' model, the subject merely notifies the observer that something happaned, and the observer queries the subject based to get the information it needs.

Let's discuss the pros and cons of both approaches:

Push

The main advantage of the 'push' model is lower coupling between the observer and the subject. The observer doesn't need to know anything about the subject in order to query it. If it needed to, we'd need to do one of the following: A- do downcasting on the side of the observer in order to invoke class-specific get methods on the subject. This is bad. B- make the Observable interface more class-specific, offering specific get methods, thus making the relationship between the observer and subject less general and making things more copupled.

By implementing the 'push' model, we avoid all of this.

However the disadvantage is less flexibility: the subject may not always know what exact information the observers need in order to send it to them. This will often mean more specific Observer intefaces, such as AgeObserver that are notified when the 'age' of the subject is changed, and HeightObserver which are sent the current height of the subject on notification.

This is one option. The other is the subject sending a whole lot of information encapsulated in an Info object of some sort and have the observers query it from there. But again, we can't be sure we're sending the correct info. So it's either this, or forcing the observers to implement more specific Observer interfaces, which tightens the coupling on the observer's side.

Pull

I already noted the disadvantages of the 'pull' model. The observers would have to know things about the subject in order to query the right information, which leads A- to downcasting (ugly), or B- favorably to more specific Observable interfaces, that offer more specific accessor methods. For example AgeObservable offers a getAge() method.

The advantage of this is more flexibility. Each observer can decide for itself what to query, without relying on the subject to send the correct information.


You should choose the strategy that is better for the specific project you're working on.

In reality, you'll always have specific Observer and Observable intefaces, so you have some coupling between the sides anyway.

So choose either 'pull' or 'push' by what fits you best.

Do all AgeObservers need simply the age of the subject? Implement the 'push' model. Less coupling and simpler.

Do all HeightObservers need varying information about the subject - aka one needs to query the age too, and some other object needs to query the weight in addition to the height? Implement the 'pull' model. This would force you to add accessors (getters) to the Observable inteface (either this or pass the actual object as a parameter in it's explicit type, but doing this through the interface allows you to deny the observers access to things that don't matter to them). This soultion creates higher coupling, but it's more flexible.

Choose what fits your situation best.

9
  • Thank you for this explanation. Regrading to my question , as you said while using pull , i need to down casting and using the getters , but what is the arg for in the observer update method? - public void update(Observable obs, Object arg) ? Commented Aug 15, 2014 at 10:14
  • I'm not sure, but I think the Object arg is meant for the 'push' model, where arg is an 'information bundle' sent to the observer.
    – Aviv Cohn
    Commented Aug 15, 2014 at 10:33
  • Yeah this is what i was thinking as well , but then why do we send the obs ? :) if we down casting we can just pull the information that we need. Commented Aug 15, 2014 at 10:35
  • 1
    Are you talking about 'push' or 'pull'? The idea in 'push' is that the observer doesn't need to know about the type of the subject. Thus you avoid down-casting. Down-casting is mostly bad becasue it creates tighter coupling between the two sides - the observer now knows the exact type of the subject, which beats the whole purpose. What if later a new class implements the Observable interface? If you don't rely on the concrete type of the subject - i.e. by not doing down-casting - the current observer code will work just as well, polymorphically, with the new subject.
    – Aviv Cohn
    Commented Aug 15, 2014 at 10:40
  • 1
    If your observer code relies on down-casting, it will need to change with every new class implementing the Observable interface, thus defeating the whole purpose of the pattern. This is an example of why 'programming to an interface, not a concrete implementation' is a good thing - code that works against an interface will work unchanged with every new class that implements the interface. If you rely on the concrete implementation - e.g. by doing downcasting, your code will need to change with every new Observable class. Beating the whole purpose.
    – Aviv Cohn
    Commented Aug 15, 2014 at 10:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.