I have an Event Login. I plan to populate that event with information such as this:
// Class A.
Login login = new Login();
login.setUsername(userName);
observer.notifyEvent(login);
The idea is for class B to get this information.
Is this bad practice? If so why?
The only forseable problem is that some other part of the software will be listening to this for no reason. When in reality only one class should be getting the information.
The only advantage is that all my classes are connected to the Observer object, but not connected to each other. In other words, if I wanted to pass the username I would need to connect A and B. Which I would only do in extreme circumstances.
Not much of a problem. - However, you may want to include the "sender" of the event in the event object so that the listener can identify where it comes from and, if needed, can get further state information from the event source.
The Observer pattern allows you to decouple the source of the event from the consumers of an event.
This is generally a good idea, even if you are only going to register one consumer.
However, I'll recommend you not to use the java.util.Observer which uses plain java.lang.Object as events, which means you must check the event object via instanceof and cast to the appropriate class.
I think its better to use an Observer or Listener implementation which supports generic types, such as Spring's ApplicationListener or Guava's EventBus which allow you to register Listener for events of particular class type, such as Login.class in your example.
Well, you probably need to dive a bit deeper into the original GoF book. For such a situation when a developer cares about different components that might be interested in different types of events the book offers the subjects collection that is maintained by the ChangeManager.
So when a component is interested in a specific type of event it passes a specific subject to the Register method so that this component won’t receive the updates for the events that represent a different subject. Additional advantage is the further decreasing of coupling.
Alternatively you might end up with building the system where any component that is plugged to the wire listens to all the events but that solution is too generic and adds lots of risks to the implementation (e.g. in the runtimes with automatic memory management like .NET the garbage collector won’t collect the subscriber while it is listening to any event – just because the ChangeManager still maintains a reference to it). It adds an additional responsibility to the subscriber - it has to do the additional filtering of events analyzing their type.
The rule of thumb is that you don’t need to subscribe for a specific event if you’re not interested to be notified when it occurs.
Referring to your example it is much better to introduce the Login subject and not to subscribe to it any component that is not interested in this specific subject.
Related
Within Java you can create an Observer-Observable set of classes in which the Observable can call the Observer. You can also in java explicitly reference an owning class instance in a child instance of another class and call the owning class instance's public functions.
Which is the better approach to take? Which is more beneficial in different scenarios, one example being Multi-Threading?
The Observer Pattern should be used whenever you don't know or don't care who is observing you. This is the key-concept in event-driven programming. You don't have any control of who is observing or what they do when you broadcast your events. Like you already mentioned in your comments, this is great for decoupling classes.
An example of a usage could be in a plugin-architecture:
You write a basic mail-server that broadcasts whenever a mail is received. You could then have a spam-plugin that validates the incoming mail, an auto-reply service that sends a reply, a forward service that redirects the mail and so on. Your plain mail server (the observable) doesn't know anything about spam, replies or forwarding. It just shouts out "Hey, a new mail is here" not knowing if anyone is listening. Then each of the plugins (the observers) does their own special thing, not knowing anything about each other. This system is very flexible and could easily be extended.
But the flexibility provided by the Observer Pattern is a two-edged sword. In the mail-server example, each plugin handles the incoming mail in total isolation from each other. This makes it impossible to setup rules like "don't reply or forward spam" because the observers doesn't know about each other - and even if they did, they wouldn't know in what order they are executed or has completed. So for the basic mail-server to solve this problem, It'll need to have references to the instances that does the spam/reply/forward actions.
So the Observer Pattern provides flexibility. You could easily add a new anti-virus plugin later, without having to modify your plain mail server code. The cost of this flexibility is loss of control of the flow of actions.
The reference approach gives you total control of the flow of actions. However you would need to modify your plain mail server code if you ever need to add support for an anti-virus plugin.
I hope this example gives you some ideas of the pros and cons of each approach.
In regards to multi-threading, one approach isn't favorable over the other.
I have read the docs for PropertyChange support and EventListenerList.
From my understanding, both serve similar purposes in holding a list of listeners and notifying them when event/propertyChange occurs.
Is it only in case of GUI applications, that EventListenerList becomes handy?. For a simple JavaBean application that does not use GUI components, is there an advantage of using one over the other.
Generally speaking, a PropertyChangeEvent occurs when some property value of the object changes (a property/value which you can read), where a (general) event could describe any kind of event (such as a change in selection or a mouse click), it doesn't have to represent a change in the state of the object
PropertyChangeSupport is part of the bean framework (in particular, but not limited to) GUI editors. This doesn't mean you can't use it, in fact, many objects rely on this functionality, such as SwingWorker and many of the objects from SwingLabs for example.
With that in mind, you should use ProperyChangeSupport when you want to notify interested parties that a property/value of an object changes and EventListenerList when you want to provide general event notification for things that are occurring within the object (but don't have to be related to a specific property or state)
The only issue I have with ProptertyChanegSupport, is it can less obvious which properties are bound and which aren't, sometimes making it difficult to get started with new objects, where as it's reasonably easy to look up all the "addListener" methods, but that's just me
While I'm sure the original intention of the EventListenrerList was for GUIs, I've used them for non-GUI work before, but you might find it easier to to use a List if you only have support for a single listener though, just saying
as PropertyChangeListener is just a specific "subclass" (extending interface) of EventListener - which is a marker interface and defines no methods, it is much easier to work with PropertyChangeSupport than EventListenerList - that is because if you start off with an EventListenerList you'll need to always do instanceof checks and casting to get to the actual "business" methods of your listeners (since the interface they all implement has no methods)
I was having problems with class design until i found out about observable (using observer design pattern) and thus created a small application using it which solved my problem. I was happy and proud that I had used a good principle to sovle a problem.
Now i am about to start my main application and have just read this
Making a JFrame and Observable Object
Why is the poster advised against the use of observable and instead told to use propertychangelistenr? Is there any issues with using observable?
Regards
Observer and Listener pattern are very similar. But Observer has a weakness: all observables are the same. You have to implement the logic that is based on instanceof and cast object to concrete type into Observable.update() method.
Listeners are different. There are a lot of listener types. For example mouse listener, keyboard listener etc. Each one has several callback methods (i.e. keyPressed(), keyReleased() etc). So, you never have to implement the logic that should answer the question "is it my event" into the event handler.
I think that this is why listener model is preferable.
DejanLekic and others have probably by now realized, that Observable is not an interface. That is the whole problem with Java.util.Observable!
The user of Observable has to inherit from it, and nothing else.
Consider Java.RMI or Listener events.
The only right answer is "it depends".
Observable is good when you don't care what changes about an object; you only want to know that something changed and update e.g. a cache of object properties. It's interface is just too coarse, but it could be a time-saver if you just have a need for such a thing.
On the other hand, as AlexR noticed, you also don't know what type of argument gets passed in before hand (it can even be a null value!). This makes it harder to do something useful with it. A proper listener class can have a richer API, but at the cost of adding a Listener interface and event class to your project.
PropertyChangeListener is a special case of the Observable pattern. That is I guess that both solution is good from a design perspective. Meanwhile as far as I remember PropertyChangeListener has some built in support hence it might require less coding. Ie. see: http://download.oracle.com/javase/1.4.2/docs/api/java/beans/PropertyChangeSupport.html.
The difference is in how you use them. Most of the time subclasses of Observable have no particular implementation - you inherit from it just to get a new type of Observable. Listeners on the other hand implement particular interface (or top level EventListener interface) and therefore MUST implement certain methods.
I just started playing with Observable, Observer and it's update() method and I can't understand what should I do when different actions call notifyObservers().
I mean, my Observable class has a few different methods that call setChanged() and notifyObservers() in the end. Depending on the called method, some part of the UI (Swing) needs to be updated. However, there is only one update() method implemented in the Observer class.
I though of passing something to the notifyObservers() method and then I can check the argument on update() but it doesn't feel like a good way to do it. Even if it did, what should I pass? A string with a short description of the action/method? An int, like an action/method code? Something else?
What's the best way to handle this situation?
in general you should update everything from the observable when you get a call to update(). if that is not practical, you can pass a hint to notifyObservers().
the gang-of-book says that one of the consequences of the observer pattern is:
"Unexpected updates. Because observers have no knowledge of each other's presence, they can be blind to the ultimate cost of changing the subject. A seemingly innocuous operation on the subject may cause a cascade of updates to observers and their dependent objects. Moreover, dependency criteria that aren't well-defined or maintained usually lead to spurious updates, which can be hard to track down.
This problem is aggravated by the fact that the simple update protocol provides no details on what changed in the subject. Without additional protocol to help observers discover what changed, they may be forced to work hard to deduce the changes.
"
also under implementation, they say:
"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.
"
The second parameter to update() is of type Object, so you can pass anything appropriate. As you note, the approach is rather general. In contrast, a class that maintains an EventListenerList can get a degree of run-time type safety when used as specified.
I'm reimplementing a .Net API in Java and the API specifies a whole bunch of events, ehich java doesn't implicitly support.
I'm going to use an observer pattern but due to the number of event I really don't want to clutter the interface.
I was wondering if it was a good idea to declare an "Event" class which has a subscribe method which takes an "EventHandler Interface" and a throw method.
this way I'm not cluttering my parent class with umpteen lists of subscribers because the individual events handle them.
The only issue I can see is with the arguments for the throw command, as different events would have different arguments.
The solutions I've come up with are letting the throw method accept an array of objects or, creating an interface like IEventArguemnts which can be passed to the throw command and handled by the code that has subscribed to the event, this seems to make more sense to me.
I'd appreciate any suggestions for improving this. Or any refinements.
Java has events, and also API support for events. Check out the java.util package. You'll see java.util.EventListener, java.util.EventObject and some others. There are also support classes for maintaining subscribers, etc. The AWT and Swing APIs for example are heavily event-based.
Normally the addXxxListener(XxxListener l) methods (i.e. the subscription methods) would go on the class that's firing the events, not on the event class itself. The event is the message and it's what's being fired from publisher to subscriber.
Why not just use the JavaBeans event model? If all the objects are running in the same JVM, that will work fine.
Peter Coad had some thoughts about improving the Java Observer model. Perhaps you'll find these helpful.