Having trouble getting the observer pattern working - java

I have been trying to no avail to get the observer pattern working in a relatively simple application.
I have 4 GUI classes
StarterClass (contains a CompositeWordLists and a CompositeWordListData)
CompositeWordLists (contains many CompositeListItem/s and a CompositeWordListData)
CompositeListItem
CompositeWordListData (Contains a DialogWordData)
DialogWordData
Here is my Observable
interface Observable<T> {
void addObserver(T o);
void removeObserver(T o);
void removeAllObservers();
void notifyObservers();
}
And I am creating Observers like this:
public class Observers {
private Observers(){};
interface WordListsObserver {
public void update(CompositeWordLists o);
}
interface ListItemObserver {
public void update(CompositeListItem o);
}
}
Basically I am having trouble with specifying the sort of event that occurred. For example, the CompositeWordLists class needs to know when a CompositeListItem is deleted, saved edited etc but I only have one update method ... my brain hurts now!
What is a better way of doing this?
UPDATE
Still having trouble with this, I added events and changed Observable and Observers but now I have type safety problems.
public class Observers {
private Observers(){};
/**
* #param <T> the object that is passed from the Observable
*/
interface ObservableEvent<T> {
T getEventObject();
}
/**
* Get notified about Authentication Attempts
*/
interface ObserverAuthenticationAttempt {
/**
* #param e true if authentication was successful
*/
public void update(ObservableEvent<Boolean> e);
}
/**
* Get notified about a Word Deletion
*/
interface ObserverWordDeleted {
/**
* #param e the id of the word that was deleted
*/
public void update(ObservableEvent<Integer> e);
}
}
The Observable Interface now looks like this
interface Observable<T> {
void addObserver(T o);
void removeObserver(T o);
void removeAllObservers();
<K> void notifyObservers(Observers.ObservableEvent<K> e);
}
The problem is that when I implement this I get and would have to cast K to the appropriate type, not really what I want to do.
#Override
public <K> void notifyObservers(ObservableEvent<K> e) {
for(Observers.ObserverAuthenticationAttempt o : this.observers)
o.update(e);
}
What am I doing wrong?
update 2
Actually it works better with an Observable like this, but I still need to specify the correct EventType in two different places.
interface Observable<T,K> {
void addObserver(T o);
void removeObserver(T o);
void removeAllObservers();
void notifyObservers(Observers.ObservableEvent<K> e);
}

You do not need to parametrise the Observers, but you need to parametrize the events.
public interface Observer<T> {
void notify(T event);
}
An example event:
public class WordListUpateEvent {
private final int changedIndex;
public WordListUpateEvent(int changedIndex) {
this.changedIndex = changedIndex;
}
public int getChangedIndex() {
return changedIndex;
}
}
Then you can have different interface of it for example:
public interface WordListObserver extends Observer<WordListUpateEvent> {}
and its implementations
public class ConcreteWordListObserverA implements WordListObserver {
#Override
public void notify(WordListUpateEvent event) {
System.out.println("update item at index: " + event.getChangedIndex());
}
}
on the other hand you need your Observable interface, i have splitted it in two interface in order ti make the notifyObservers method not public to the observers (you will see it later):
public interface Observable<T> extends ObservableRegistration<T> {
void notifyObservers(T event);
}
public interface ObservableRegistration<T> {
void addObserver(Observer<T> o);
void removeObserver(Observer<T> o);
void removeAllObservers();
}
If you would have several observables in a subject, you can not implemnt the Observalbe interface direct to your subject, so you need a seperate implementation class:
public class ObservableImpl<T> implements Observable<T>{
private final List<Observer<T>> observers = new ArrayList<Observer<T>>();
#Override
public void addObserver(Observer<T> o) {
this.observers.add(o);
}
#Override
public void removeObserver(Observer<T> o) {
this.observers.remove(o);
}
#Override
public void removeAllObservers() {
this.observers.clear();
}
#Override
public void notifyObservers(T event) {
for(Observer<T> observer : observers) {
observer.notify(event);
}
}
}
Now you can use the implementation in your subject:
public class Subject {
private Observable<WordListUpateEvent> wordListObservable = new ObservableImpl<WordListUpateEvent>();
//private Subject<OtherEvent> otherObservable = new ObservableImpl<WordListUpateEvent>();
public ObservableRegistration<WordListUpateEvent> getWordListObservableRegistration() {
return this.wordListObservable;
}
// public ObservableRegistration<OtherEvent> getOtherRegistration() {
// return this.otherObservable;
// }
public void doSomething() {
this.wordListObservable.notifyObservers(new WordListUpateEvent(42));
}
}
And this is how you can connect the observer and the subject:
public class Start {
public static void main(String[] args) {
Subject subject = new Subject();
subject.getWordListObservableRegistration().addObserver(new ConcreteWordListObserverA());
subject.getWordListObservableRegistration().addObserver(new ConcreteWordListObserverA());
subject.doSomething();
}
}

I would create an Observer interface, containing a public void update(ObservableEvent oe) method, and an ObserverEvent interface. After that, you can create specific class for each of your events.

http://download.oracle.com/javase/1.4.2/docs/api/java/util/Observer.html
http://www.java2s.com/Code/Java/Design-Pattern/Observableandobserver.htm
The Java Observer's update method has the Object argument. You can pass any Object, thus you can create your own "UpdateMessage" Object that can contain the updated object and additional information about what happend (deleted, saved etc.).

Related

Referencing boolean in interface

I ran into a bit of an issue and was hoping someone could tell me what I'm missing here.
for some context I have the following methods:
private boolean windowork;
public class WinidowMalfunction extends Event {
ControllerException newException = new ControllerException("Error:");
public WinidowMalfunction(long delayTime) {
super(delayTime);
}
public void action() throws ControllerException {
windowork = false;
someThingWentWrongHere(1, "Error at WinidowMalfunction");
}
}
private boolean poweron;
public class PowerOut extends Event {
public PowerOut(long delayTime) {
super(delayTime);
}
public void action() throws ControllerException {
poweron = false;
someThingWentWrongHere(2, "Error at powerOut event");
}
}
and I'm creating interface Fixable where I need to change the value of poweron and windowork to change their values to true. but I can't get the FIxable to accept the references. they are all in the same class so is there a way to reference these boolean function in an interface
EDIT:
Assignment question:
In this part, we add functionality for restoring the saved GreenhouseControls object and having it resume execution where it left off. It demonstrates the use of interfaces and the capability of Java methods to return objects.
Create the following interface
interface Fixable {
// turns Power on, fix window and zeros out error codes
void fix ();
// logs to a text file in the current directory called fix.log
// prints to the console, and identify time and nature of
// the fix
void log();
}
You can do something like this:
interface Fixable {
public boolean setTrue();
}
class Foo implements Fixable {
private boolean windowork = false;
public void setTrue() {
windowork = true;
}
}
class Bar implements Fixable {
private boolean poweron = false;
public void setTrue() {
poweron = true;
}
}
The only advantage of the above is if you had an array of Fixable objects you could iterate thru them and do this.
for (Fixable f : fixableArray) {
f.setTrue();
}
An interface can be designed in a way to read-write a boolean property that resides in the class/instance.
public interface Somename {
public boolean isPowerOn();
public void setPowerTo(boolean arg);
}

Observer Uml & Java

I really need your help for a question: the right implementation of pattern Observer. The fact is that I have no guarantees about doing right so I just would like to know if there are inconsistencies between UML and code below, please report me any minimum mistake/improvable detail in both parties. I would be so much grateful to anyone, thanks in advance.
UML:
JAVA CODE:
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
public class ConcreteSubject implements Subject {
private int my_state;
private ArrayList<Observer> observers;
public ConcreteSubject(){
observers=new ArrayList<Observer>();
}
public void registerObserver(Observer o){
observers.add(o);
}
public void removeObserver(Observer o){
observers.remove(o);
}
public void notifyObservers(){
for(Observer o : observers)
o.update();
}
//PULL Mode -> Observer musts grab the state of the subject
public int getState(){
return my_state;
}
public void setState(int state){
my_state=state;
}
}
public interface Observer {
public void update(); //In PULL mode update don't need the state of the subject in argument
}
public class ConcreteObserver implements Observer {
private ConcreteSubject my_subject;
public ConcreteObserver(ConcreteSubject subject){
my_subject=subject;
}
public void update(){
System.out.println("The state is: "+my_subject.getState());
}
}
You can consider to implement Subject as abstract class, so ConcreteSubject will care only about change of the state and notification of the observers.
With this approach you can have more ConcreteSubjects.
Check example of the Observer pattern.

How to properly convert Listeners to Reactive (Observables) using RxJava?

I'm using a multiplayer Game Client that's called AppWarp (http://appwarp.shephertz.com), where you can add event listeners to be called back when event's happen, let's assume we'll be talking about the Connection Listener, where you need to implement this interface:
public interface ConnectionRequestListener {
void onConnectDone(ConnectEvent var1);
void onDisconnectDone(ConnectEvent var1);
void onInitUDPDone(byte var1);
}
My goal here is to mainly create a Reactive version of this client to be used in my Apps Internally instead of using the Client itself directly (I'll also rely on interfaces later instead of just depending on the WarpClient itself as in the example, but that's not the important point, please read my question at the very end).
So what I did is as follows:
1) I introduced a new event, named it RxConnectionEvent (Which mainly groups Connection-Related events) as follows:
public class RxConnectionEvent {
// This is the original connection event from the source client
private final ConnectEvent connectEvent;
// this is to identify if it was Connection / Disconnection
private final int eventType;
public RxConnectionEvent(ConnectEvent connectEvent, int eventType) {
this.connectEvent = connectEvent;
this.eventType = eventType;
}
public ConnectEvent getConnectEvent() {
return connectEvent;
}
public int getEventType() {
return eventType;
}
}
2) Created some event types as follows:
public class RxEventType {
// Connection Events
public final static int CONNECTION_CONNECTED = 20;
public final static int CONNECTION_DISCONNECTED = 30;
}
3) Created the following observable which emits my new RxConnectionEvent
import com.shephertz.app42.gaming.multiplayer.client.WarpClient;
import com.shephertz.app42.gaming.multiplayer.client.events.ConnectEvent;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Action0;
import rx.subscriptions.Subscriptions;
public class ConnectionObservable extends BaseObservable<RxConnectionEvent> {
private ConnectionRequestListener connectionListener;
// This is going to be called from my ReactiveWarpClient (Factory) Later.
public static Observable<RxConnectionEvent> createConnectionListener(WarpClient warpClient) {
return Observable.create(new ConnectionObservable(warpClient));
}
private ConnectionObservable(WarpClient warpClient) {
super(warpClient);
}
#Override
public void call(final Subscriber<? super RxConnectionEvent> subscriber) {
subscriber.onStart();
connectionListener = new ConnectionRequestListener() {
#Override
public void onConnectDone(ConnectEvent connectEvent) {
super.onConnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_CONNECTED));
}
#Override
public void onDisconnectDone(ConnectEvent connectEvent) {
super.onDisconnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_DISCONNECTED));
}
// not interested in this method (for now)
#Override
public void onInitUDPDone(byte var1) { }
private void callback(RxConnectionEvent rxConnectionEvent)
{
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(rxConnectionEvent);
} else {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
};
warpClient.addConnectionRequestListener(connectionListener);
subscriber.add(Subscriptions.create(new Action0() {
#Override
public void call() {
onUnsubscribed(warpClient);
}
}));
}
#Override
protected void onUnsubscribed(WarpClient warpClient) {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
4) and finally my BaseObservable looks like the following:
public abstract class BaseObservable<T> implements Observable.OnSubscribe<T> {
protected WarpClient warpClient;
protected BaseObservable (WarpClient warpClient)
{
this.warpClient = warpClient;
}
#Override
public abstract void call(Subscriber<? super T> subscriber);
protected abstract void onUnsubscribed(WarpClient warpClient);
}
My question is mainly: is my implementation above correct or should I instead create separate observable for each event, but if so, this client has more than 40-50 events do I have to create separate observable for each event?
I also use the code above as follows (used it in a simple "non-final" integration test):
public void testConnectDisconnect() {
connectionSubscription = reactiveWarpClient.createOnConnectObservable(client)
.subscribe(new Action1<RxConnectionEvent>() {
#Override
public void call(RxConnectionEvent rxEvent) {
assertEquals(WarpResponseResultCode.SUCCESS, rxEvent.getConnectEvent().getResult());
if (rxEvent.getEventType() == RxEventType.CONNECTION_CONNECTED) {
connectionStatus = connectionStatus | 0b0001;
client.disconnect();
} else {
connectionStatus = connectionStatus | 0b0010;
connectionSubscription.unsubscribe();
haltExecution = true;
}
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
fail("Unexpected error: " + throwable.getMessage());
haltExecution = true;
}
});
client.connectWithUserName("test user");
waitForSomeTime();
assertEquals(0b0011, connectionStatus);
assertEquals(true, connectionSubscription.isUnsubscribed());
}
I suggest you avoid extending the BaseObservable directly since it's very error prone. Instead, try using the tools Rx itself gives you to create your observable.
The easiest solution is using a PublishSubject, which is both an Observable and a Subscriber. The listener simply needs to invoke the subject's onNext, and the subject will emit the event. Here's a simplified working example:
public class PublishSubjectWarpperDemo {
public interface ConnectionRequestListener {
void onConnectDone();
void onDisconnectDone();
void onInitUDPDone();
}
public static class RxConnectionEvent {
private int type;
public RxConnectionEvent(int type) {
this.type = type;
}
public int getType() {
return type;
}
public String toString() {
return "Event of Type " + type;
}
}
public static class SimpleCallbackWrapper {
private final PublishSubject<RxConnectionEvent> subject = PublishSubject.create();
public ConnectionRequestListener getListener() {
return new ConnectionRequestListener() {
#Override
public void onConnectDone() {
subject.onNext(new RxConnectionEvent(1));
}
#Override
public void onDisconnectDone() {
subject.onNext(new RxConnectionEvent(2));
}
#Override
public void onInitUDPDone() {
subject.onNext(new RxConnectionEvent(3));
}
};
}
public Observable<RxConnectionEvent> getObservable() {
return subject;
}
}
public static void main(String[] args) throws IOException {
SimpleCallbackWrapper myWrapper = new SimpleCallbackWrapper();
ConnectionRequestListener listner = myWrapper.getListener();// Get the listener and attach it to the game here.
myWrapper.getObservable().observeOn(Schedulers.newThread()).subscribe(event -> System.out.println(event));
listner.onConnectDone(); // Call the listener a few times, the observable should print the event
listner.onDisconnectDone();
listner.onInitUDPDone();
System.in.read(); // Wait for enter
}
}
A more complex solution would be to use one of the onSubscribe implementations to create an observable using Observable.create(). For example AsyncOnSubscibe. This solution has the benefit of handling backperssure properly, so your event subscriber doesn't become overwhelmed with events. But in your case, that sounds like an unlikely scenario, so the added complexity is probably not worth it.

Java Observer Pattern - How to remove observers during update(notify) loop/iteration?

I am very new to java so sorry in advance if anything I say sounds newbish, be gentle.
I have implemented a basic Observer Pattern. Some observers should only listen to one update and then immediately remove themselves from the observers/listeners list. However, whenever I tried doing that I got the famous java.util.concurrentmodificationexception error.
I'm obviously getting this error because I'm changing the list while still iterating over it, yet I am still unsure what is the right solution. I'm wondering if I'm even doing this the right way. If I am, what would be the needed fix to make it work? And if I'm not, I'd like to get suggestions for a better way of achieving what I'm trying to do.
Here's my code:
public interface Listener {
public void onValueChange(double newValue);
}
public class Observed {
private int value;
List<Listener> listeners = new ArrayList<>();
public void addListener(Listener toAdd) {
listeners.add(toAdd);
}
public void removeListener(Listener toRemove) {
listeners.remove(toRemove);
}
public void changeValue(double newValue) {
value = newValue;
for (Listener l : listeners) l.onValueChange(newValue);
}
}
public class SomeClassA implements Listener{
private Observed observed;
SomeClassA(Observed observed) {
this.observed = observed;
}
#Override
public void onValueChange(double newValue) {
System.out.println(newValue);
observed.removeListener(this);
}
}
public class SomeClassB implements Listener{
#Override
public void onValueChange(double newValue) {
System.out.println(newValue);
}
}
public class ObserverTest {
public static void main(String[] args) {
Observed observed = new Observed();
SomeClassA objectA = new SomeClassA(observed);
SomeClassB objectB = new SomeClassB();
observed.addListener(objectB);
observed.addListener(objectA);
observed.changeValue(4);
}
}
one ways is to go fo CopyOnWriteArraylist instead of ArrayList .
CopyOnWriteArraylist is a thread-safe variant of ArrayList in which
all mutative operations (add, set, and so on) are implemented by
making a fresh copy of the underlying array.
Reason why its thrown in your case
you are modifying a collection directly while it is iterating over the collection under method changeValue()
You can not remove items from a collection while you are iterating over it. That is, unless you use the Iterator#remove method. Since that is not a possibility in this case, an alternative is make a copy of your listener list and iterate over that instead. In that case the original listener list is free to be manipulated by the individual listeners:
public void changeValue(double newValue) {
value = newValue;
List<Listener> copyOfListeners = new ArrayList<Listener>(listeners);
for(Listener l : copyOfListeners) {
l.onValueChange(newValue);
}
}
the code below works, so you can try whatever it does.
import java.util.Observable;
import java.util.Observer;
class Model extends Observable {
public void setX(double x) {
this.x=x;
System.out.println("setting x to "+x);
setChanged();
notifyObservers();
}
double x;
}
class A implements Observer {
A(Model model) {
this.model=model;
}
#Override public void update(Observable arg0,Object arg1) {
System.out.println(getClass().getName()+" "+((Model)arg0).x);
((Model)arg0).deleteObserver(this);
}
Model model;
}
class B implements Observer {
#Override public void update(Observable arg0,Object arg1) {
System.out.println(getClass().getName()+" "+((Model)arg0).x);
}
}
public class So19197579 {
public static void main(String[] arguments) {
Model model=new Model();
model.addObserver(new A(model));
model.addObserver(new B());
model.setX(4);
model.setX(8);
}
}

User defined Listener in Java

In my web app, during some change over the object, i need to send a mail about the changes happened in the object.
My question is how to write a listener for this.
Please give me some article regarding this.
Thanks
A typical implementation could be like this: your object is observable. So every time, one of the (observed) values changes, an event is fired and all registered listeners are notified. One of those listeners now would be designed to take the notification and create and send an EMail (Java Mail API)
Let's take a sample bean which we make observable:
public class Bean implements Observable{
// code to maintain listeners
private List<Listener> listeners = new ArrayList<Listener>();
public void add(Listener listener) {listeners.add(listener);}
public void remove(Listener listener) {listeners.remove(listener);}
// a sample field
private int field;
public int getField() {return field;}
public int setField(int value) {
field = value;
fire("field");
}
// notification code
private void fire(String attribute) {
for (Listener listener:listeners) {
fieldChanged(this, attribute);
}
}
}
The Listener interface:
public interface Listener {
public void fieldChanged(Object source, String attrbute);
}
The Observable interface:
public interface Observable {
public void add(Listener listener);
public void remove(Listener listener);
}
And the EMailer:
public class Sender implements Listener {
public void register(Observable observable) {observable.add(this);}
public void unregister(Observable observable) {observable.remove(this);}
public void fieldChanged(Object source, String attribute) {
sendEmail(source, attribute); // this has to be implemented
}
}
EDIT
Corrected an ugly mistake in the setter method - now the event is fired after the property has been set. Was the other way round, with the side effect, that if a listener read the changed property, he still saw the old, unchanged value...
If you simply wish to know about the properties of an object being modified I would recommend using a PropertyChangeListener. That way you can use the PropertyChangeSupport utility class to manage your listener instances and the firing of events. You also avoid reinventing the wheel.
For more bespoke event firing I would recommend defining your own listener interface.
Example Class
public class MyBean {
private final PropertyChangeSupport support;
private int i;
private boolean b;
public MyBean() {
this.support = new PropertyChangeSupport(this);
}
// Accessors and Mutators. Mutating a property causes a PropertyChangeEvent
// to be fired.
public int getI() { return i; }
public void setI(int i) {
int oldI = this.i;
this.i = i;
support.firePropertyChange("i", oldI, this.i);
}
public boolean getB() { return b; }
public void setB(boolean b) {
boolean oldB = this.b;
this.b = b;
support.firePropertyChange("b", oldB, this.b);
}
// Wrapper methods that simply delegate listener management to
// the underlying PropertyChangeSupport class.
public void addPropertyChangeListener(PropertyChangeListener l) {
support.addPropertyChangeListener(l);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
// You would typically call this method rather than addPropertyChangeListener(PropertyChangeListener)
// in order to register your listener with a specific property.
// This then avoids the need for large if-then statements within your listener
// implementation in order to check which property has changed.
if (!"i".equals(propertyName) && !"b".equals(propertyName)) {
throw new IllegalArgumentException("Invalid property name: " + propertyName);
}
support.addPropertyChangeListener(propertyName, l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
support.removePropertyChangeListener(l);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
support.removePropertyChangeListener(propertyName, l);
}
}
Example Usage
// Create a new instance of our observable MyBean class.
MyBean bean = new MyBean();
// Create a PropertyChangeListener specifically for listening to property "b".
PropertyChangeListener listener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
assert "b".equals(evt.getPropertyName());
boolean oldB = (Boolean) evt.getOldValue();
boolean newB = (Boolean) evt.getNewValue();
System.err.println(String.format("Property b updated: %b -> %b, oldB, newB));
}
}
// Register listener with specific property name. It will only be called back
// if this property changes, *not* the "i" int property.
bean.addPropertyChangeListener("b", listener);
You should use the Observer Design Pattern. This pattern uses these classes :
java.util.Observable
java.util.Observer
Here is an example.
The observer :
public class EmailObserver implements Observer
{
#Override
public void update(Observable obj, Object arg)
{
if (obj instanceof YourObject)
{
// TODO Send the mail or whatever, you have access to the modified object through obj
// In arg you can put some additional parameter, like the modified field
}
}
}
The Observable Object :
public static class YourObject extends Observable
{
public void setSomething(Object parameter)
{
// TODO some modification in YourObject
setChanged(); // From Observable : the object has changed
notifyObservers(parameter); // Notify the observer about the change
}
}
And the main class :
public static void main(String[] args)
{
// Create YourObject
YourObject o = new YourObject();
// create an observer
EmailObserver emailObserver = new EmailObserver();
// subscribe the observer to your object
o.addObserver(emailObserver);
// Now you can modify your object, changes will be notified by email
o.setSomething(...);
}
Use Observer design pattern http://en.wikipedia.org/wiki/Observer_pattern.
http://java-x.blogspot.com/2007/01/implementing-observer-pattern-in-java.html

Categories

Resources