Observer pattern: case of multiple registration of the same instance - oop

I'm studying the observer, a kind of design pattern.
The observable object contains a list of observers. A list can accept redundant an observer instance. So we can limit this redundancy using a hash set instead of a list.
My question is, if we allow redundant registration of the same observer instance, is there any example that the observer is registered more than one time? Why the same observer is registered to the same observable multiple times?

One observable may produce several different types of event notifications. One observer may be interested in registering for a number of these notifications. Obviously you could design this scenario in different ways; but one way is to maintain all registrations in a single list.
The GoF does mention on page 296,
It's up to the observer to handle or ignore a notification.
This implies an observer needs to be aware of any potential for redundancy and react appropriately.

Related

"Delegates or NSNotifications" Adjudging performance of code?

In my application, I have to display image files as a list in tableview, present them in full size and as multiple thumbnails. Hence basically I developed three seperate classes to handle these three views. Now to perform any file operations, I can think of two approaches:
Create appdelegate objects for all these classes, handle them accordingly. When one operation on a photo file is performed in one class, all other classes are notified using NSNotification, keeping the obeserver as Appdelegate object.
Create locally objects for these classes as and when required and assign delegates for performing file operations from one class to other by calling relevant methods.
However, I was not able to judge Which approach would be better in terms of memory usage and performance? Thanks in advance.
Using a one-to-one relationship with direct messaging is the simpler relationship and means of communication/messaging. Favor the delegate callback -- Number 2.
It is also easy to make this design bidirectional -- if the view goes offscreen, you could perform a cancellation. If the load fails, it is easier to inform the controller.
NSNotifications are comparably heavyweight. Not necessary.
Storing a bunch of stuff in a singleton (app delegate) can result in several unnecessarily retained objects. If your program is concurrent, then that can add even more complexity. There's no need for any of this complexity or introduction of mutable global state, and there is no reason presented whereby the objects should have a much larger scope of access and lifetime.
You can optimize for specific needs beyond that, but I don't see any at this time.
It depends a lot on the code and how you are structuring your app. I general use delegates in the following situation:
Where the delegate object exists before and after the main object that needs it. In other words the main object does not need to worry about the lifecycle of it's delegate.
Where the relationship between an object and it's delegate object is a strict one to one. In other words only one delegate object needs to interact with the main object. I have seen situations where delegates are swapped in and out and I would not recommend such code.
Where the main object needs information from the delegate.
I would use notifications where:
Multiple objects need to know of about things happening in another class.
Where the main class does not need to interact with the other classes or even know they exist.
Which ever you choose I would not have more than one file management object for each image. The simple reason being that having multiple means you need to ensure that they all have the same state and therefore are communicating with each other. Otherwise bugs will creep in.

Why should the observer pattern be deprecated?

I've noticed that my dependency injected, observer-pattern-heavy code (using Guava's EventBus) is often significantly more difficult to debug than code I've written in the past without these features. Particularly when trying to determine when and why observer code is being called.
Martin Oderski and friends wrote a lengthy paper with an especially alluring title, "Deprecating the Observer Pattern" and I have not yet made the time to read it.
I'd like to know what is so wrong with the observer pattern and so much better about the (proposed or other) alternatives to lead such bright people to write this paper.
As a start, I did find one (entertaining) critique of the paper here.
Quoting directly from the paper:
To illustrate the precise problems of the observer pattern,
we start with a simple and ubiquitous example: mouse dragging.
The following example traces the movements of the
mouse during a drag operation in a Path object and displays
it on the screen. To keep things simple, we use Scala closures
as observers.
var path: Path = null
val moveObserver = { (event: MouseEvent) =>
path.lineTo(event.position)
draw(path)
}
control.addMouseDownObserver { event =>
path = new Path(event.position)
control.addMouseMoveObserver(moveObserver)
}
control.addMouseUpObserver { event =>
control.removeMouseMoveObserver(moveObserver)
path.close()
draw(path)
}
The above example, and as we will argue the observer
pattern as defined in [25] in general, violates an impressive
line-up of important software engineering principles:
Side-effects Observers promote side-effects. Since observers
are stateless, we often need several of them to simulate
a state machine as in the drag example. We have to save
the state where it is accessible to all involved observers
such as in the variable path above.
Encapsulation As the state variable path escapes the scope
of the observers, the observer pattern breaks encapsulation.
Composability Multiple observers form a loose collection
of objects that deal with a single concern (or multiple,
see next point). Since multiple observers are installed at
different points at different times, we can’t, for instance,
easily dispose them altogether.
Separation of concerns The above observers not only trace
the mouse path but also call a drawing command, or
more generally, include two different concerns in the
same code location. It is often preferable to separate the
concerns of constructing the path and displaying it, e.g.,
as in the model-view-controller (MVC) [30] pattern.
Scalablity We could achieve a separation of concerns in our
example by creating a class for paths that itself publishes
events when the path changes. Unfortunately, there is no
guarantee for data consistency in the observer pattern.
Let us suppose we would create another event publishing
object that depends on changes in our original path, e.g.,
a rectangle that represents the bounds of our path. Also
consider an observer listening to changes in both the
path and its bounds in order to draw a framed path. This
observer would manually need to determine whether the
bounds are already updated and, if not, defer the drawing
operation. Otherwise the user could observe a frame on
the screen that has the wrong size (a glitch).
Uniformity Different methods to install different observers
decrease code uniformity.
Abstraction There is a low level of abstraction in the example.
It relies on a heavyweight interface of a control
class that provides more than just specific methods to install
mouse event observers. Therefore, we cannot abstract
over the precise event sources. For instance, we
could let the user abort a drag operation by hitting the escape
key or use a different pointer device such as a touch
screen or graphics tablet.
Resource management An observer’s life-time needs to be
managed by clients. Because of performance reasons,
we want to observe mouse move events only during a
drag operation. Therefore, we need to explicitly install
and uninstall the mouse move observer and we need to
remember the point of installation (control above).
Semantic distance Ultimately, the example is hard to understand
because the control flow is inverted which results
in too much boilerplate code that increases the semantic
distance between the programmers intention and
the actual code.
[25] E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design
patterns: elements of reusable object-oriented software.
Addison-Wesley Longman Publishing Co., Inc., Boston, MA,
USA, 1995. ISBN 0-201-63361-2.
I believe the Observer pattern has the standard drawbacks that come with decoupling things. The Subject gets decoupled from Observer but you cannot just look at its source code and find out who observes it. Hardcoded dependencies are usually easier to read and think about but they are harder to modify and reuse. It's a tradeoff.
As to the paper, it does not address the Observer pattern itself but a particular usage of it. In particular: multiple stateless Observer objects per single object being observed. This has the obvious drawback of the separate observers needing to synchronize with each other ("Since observers are stateless, we often need several of them to simulate
a state machine as in the drag example. We have to save
the state where it is accessible to all involved observers
such as in the variable path above.")
The above drawback is specific to this kind of usage, not to the Observer pattern itself. You could as well create a single (stateful!) observer object that implements all the OnThis, OnThat,OnWhatever methods and get rid of the problem of simulating a state machine across many stateless objects.
I will be brief because I'm new to the topic (and didn't read that specific article yet).
Observer Pattern is intuitively wrong: The Object to be observed knows who is observing (Subject<>--Observer).
That is against real-life (in event-based scenarios). If I scream, I have no idea who is listening; if a lightening, hits the floor... lightning doesn't know that there is a floor till it hits!. Only Observers know what they can observe.
When this kind of of things happen then software use to be a mess -because constructed against our way of thinking-.
It is as if and object knew what other objects can call his methods.
IMO a layer such as "Environment" is the one in charge of taking the events and notifying the affected. (OR mixes the event and the generator of that event)
Event-Source (Subject) generates events to the Environment. Environment delivers the event to the Observer. Observer could register to the kind of events that affects him or it is actually defined in the Environment. Both possibilities make sense (but I wanted to be brief).
In my understanding the Observer Pattern puts together environment & subject.
PS. hate to put in paragraphs abstract ideas! :P

Observer pattern-The subject keeps track of the items to be observed by the observer

Observer pattern-
Assumption:
Out of the 10 items, the observer only wants to be subscribed to 3.
Subject calls a function of the observer to let him know that there
are some updates.
Now, is it subject's responsibility to send the updates pertaining to only 3 items to the observer?
OR
Subject can simply tell the observer that there are updates - go fetch whichever you want out of 10?
Which is the correct way out? Does it matter?
It's the Subject to keep a list of Observers who are interested in this subject, and notify these Observers by calling its update method.
Observer does NOT keep a list of subjects which it is interested in.
Based on this, when a subject is updated, the subject will call the update(..) method or something similar of those Observers in its list. subject can either encapsulate the changes in an object as a parameter of the method, Or pass the this object of this subject (observers get the interested data by calling subject's methods themselves).
I'd rather go with specific notifications about different events. Usually with push model. Like Hey, I just earned some money. Here is actual amount I have earned. Instead of Hey, something happened to me.. Latter moves all logic to clients (observers). Clients should verify what has changed and this verification logic will be duplicated if you have several clients. Actually if you don't have other observers, you don't need this pattern :)
Also specific notifications allow to subscribe only to events which clients are interested in. So, observers will not be bothered when something other happened (i.e. when subject watched a movie).
Now, is it subject's responsibility to send the updates pertaining to only 3 items to the observer?
OR
Subject can simply tell the observer that there are updates - go fetch whichever you want out of 10?
Which is the correct way out? Does it matter?
There is no absolute right answer here.
These are implementation choices, and in fact are mentioned in the implementation section for Observer in Design Patterns:
_6. Avoiding observer-specific update protocols: the push and pull models. Implementations of the Observer pattern often have the subject broadcast additional information about the change. The subject passes this information as an argument to Update. The amount of information may vary widely.
At one extreme, which we call the push model, the subject sends observers detailed information about the change, whether they want it or not. At the other extreme is the pull model; the subject sends nothing but the most minimal notification, and observers ask for details explicitly thereafter.
The pull model emphasizes the subject's ignorance of its observers, whereas the push model assumes subjects know something about their observers' needs. The push model might make observers less reusable, because Subject classes make assumptions about Observer classes that might not always be true. On the other hand, the pull model may be inefficient, because Observer classes must ascertain what changed without help from the Subject.
_7. Specifying modifications of interest explicitly. You can improve update efficiency by extending the subject's registration interface to allow registering observers only for specific events of interest. When such an event occurs, the subject informs only those observers that have registered interest in that event. One way to support this uses the notion of aspects for Subject objects. To register interest in particular events, observers are attached to their subjects using
void Subject::Attach(Observer*, Aspect& interest);
where interest specifies the event of interest. At notification time, the subject supplies the changed aspect to its observers as a parameter to the Update operation. For example:
void Observer::Update(Subject*, Aspect& interest);
If it makes more sense in your situation to use the push model, so the subject has a bit more knowledge of the observers' needs, and to use an aspect model so that the observers can register interest in particular portions of the subject's data, go for it!
I usually prefer to use the pull model and accept that the observer has a bit of detailed knowledge of the subject (it's simpler to implement), but what you're proposing is probably fine in your situation.

Best way to determine the behavior of a view's containing view

My situation:
ClassA may or may not have a parent of type ClassB. Therefore saying [instanceOfA.superview somethingClassBSpecific]; is half hazardous. Plus, Xocde will get pissy, for good reason.
Is the recommendation here to dispatch a notification, or do some logic on the superview, e.g.,
if([objectOfA.superview respondsToSelector:somethingClassBSpecific] != nil){
//...
}
Or create a delegate of type ClassB where the situation permits?
As is so often the case, it depends. Using the view hierarchy, notifications, and delegation are three different ways that objects can communicate with each other. Deciding which of those (if any) is most appropriate requires thinking about how the objects in question are related to each other.
Notifications provide very loose (nearly zero) coupling between objects. They also provide one-to-many communication -- you post a notification, and every object that's listening for that notification will get the message. But notifications aren't always appropriate; communication is mainly in one direction only, and abusing the notification mechanism can lead to performance problems.
Delegation gives you a way to customize the behavior of an object. The most obvious example is the application delegate. Most every iOS application is based on the same class: UIApplication. UIApplication is exactly the same for every app even though each app does its own thing. The application object uses a delegate to provide the customization that gives the application its unique behavior.
The view hierarchy is another way that (some) objects are connected to each other. If the behavior you're implementing is a) part of a view and b) dependent on that view's relationship with other views, then it may make sense to use the superview and subviews properties.
So, what kind of functionality are you trying to implement?
This depends on your logical model. If you have an instance of a class implementing a protocol with optional methods, then using respondsToSelector: is appropriate when you are trying to call one of these optional methods. If you want the method you call to be required, create a do-nothing "guard" in the classes that you pass. Both techniques are valid, it's only a matter of whether or not you'd like your users to be conscious of the need to implement a specific method.

Observer pattern or Callback?

I have to do a design of a DownloadManager, but my main question is related to the notifications that a Download can send to the DownloadManager like onUpdate() to update a progress bar, onError(), onFinish(), etc. Somehow the DownloadManager has to receive this notifications from its Downloads.
I've thought 2 possible ways:
Observer pattern
Callbacks
Observer pattern
Basically there are 1 Observable and N Observers. In my case the DownloadManager has te be an Observer and the Downloads the Observables, so the relation is N Observables 1 Observer, just the opposite.
The advantage is to centralize all the possible notifications in one method, the notify() or update() (from java) method from the Observers, in my case only the DownloadManager. I can pass a param to the notify() method with the code of the notification.
Disadvantage? I'm using an oop pattern for a thing that can be done easily with a callback. Also, N observables 1 observer it's something weird, at least with the observer pattern because this pattern was done for 1 observable N observers, so I really won't be using the observer pattern.
Callback
Very similar to the observer pattern. The DownloadManager implements a "listener" (interface). This listener implements the notification functions onFinish(), onUpdate(), etc. Then this listener must be registered in all Downloads, so when a Download finishes it will call listener.onFinish(). Additionally I can pass parameters to this methods from the Downloads, like in the observer pattern.
Advantage: Easily usage.
Disadvantage: None.
I will probably use a callback because in my opinion it makes no sense to use an observer pattern for 1 observer N observables.
And you, which option will use?
Callbacks FTW. It is simpler, and in the vast majority of cases, simplicity influences every other aspect of the project in a positive way, including development, debugging, optimization, documentation and further maintenance.
The observer is more flexible/scalable. Is not that weird after all the usage you mentioned for the observer pattern. Patters are after all just guidlines, if you need to change it a bit to fit your needs then go for it.
Consider the case when you have multiple DownloadManagers (maybe this is not a valid use case for your particular situation). You will need to register both of them. If you have even more then you will have to register all of them. Pretty long list, plus you need to implement listeners management in the Downloads
There is also one option, which is opposite to Observer/Callback approach. You can turn clients of DownloadManager from passive to active players of the show. Instead of waiting for a message from the manager they will regularly request its status.
This way your download process will look much smoother to the end-user. And you will be able to control it better.
Of course, you will have to use two threads. Or you will have to teach the DownloadManager to work in small steps, returning control to its client, instead of running one unbreakable piece of work.
observer is more suitable because Manager need to send request to many instances.
It is easy to implement. In implementation point of it will be more scalable in terms of progress bar functionality and how much downloaded each one and Total % Download