我一直试图让观察者模式在一个相对简单的应用程序中运行。
我有4个GUI类
CompositeWordLists
和CompositeWordListData
)CompositeListItem
/ s和CompositeWordListData
)
DialogWordData
)
这是我的Observable
interface Observable<T> {
void addObserver(T o);
void removeObserver(T o);
void removeAllObservers();
void notifyObservers();
}
我正在创建这样的观察者:
public class Observers {
private Observers(){};
interface WordListsObserver {
public void update(CompositeWordLists o);
}
interface ListItemObserver {
public void update(CompositeListItem o);
}
}
基本上我在指定发生的事件类型方面遇到了麻烦。例如,CompositeWordLists
类需要知道何时删除CompositeListItem
,保存编辑等,但我只有一种更新方法......我的大脑现在受伤了!
这样做的更好方法是什么?
仍有问题,我添加了事件并更改了Observable和Observers,但现在我遇到了类型安全问题。
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);
}
}
Observable Interface现在看起来像这样
interface Observable<T> {
void addObserver(T o);
void removeObserver(T o);
void removeAllObservers();
<K> void notifyObservers(Observers.ObservableEvent<K> e);
}
问题在于,当我实现这个时,我得到并且必须将K转换为适当的类型,而不是我想要做的。
@Override
public <K> void notifyObservers(ObservableEvent<K> e) {
for(Observers.ObserverAuthenticationAttempt o : this.observers)
o.update(e);
}
我做错了什么?
实际上它对于像这样的Observable效果更好,但我仍然需要在两个不同的地方指定正确的EventType。
interface Observable<T,K> {
void addObserver(T o);
void removeObserver(T o);
void removeAllObservers();
void notifyObservers(Observers.ObservableEvent<K> e);
}
答案 0 :(得分:3)
您无需对观察者进行参数化,但您需要对事件进行参数化。
public interface Observer<T> {
void notify(T event);
}
一个示例事件:
public class WordListUpateEvent {
private final int changedIndex;
public WordListUpateEvent(int changedIndex) {
this.changedIndex = changedIndex;
}
public int getChangedIndex() {
return changedIndex;
}
}
然后你可以有不同的界面,例如:
public interface WordListObserver extends Observer<WordListUpateEvent> {}
及其实现
public class ConcreteWordListObserverA implements WordListObserver {
@Override
public void notify(WordListUpateEvent event) {
System.out.println("update item at index: " + event.getChangedIndex());
}
}
另一方面,你需要你的Observable接口,我已经将它拆分为两个接口,以使notifyObservers方法不公开给观察者(你稍后会看到):
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();
}
如果你在一个主题中有几个observable,你就不能直接向你的主题实现Observalbe接口,所以你需要一个单独的实现类:
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);
}
}
}
现在您可以在主题中使用该实现:
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));
}
}
这就是你如何连接观察者和主题:
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();
}
}
答案 1 :(得分:0)
我将创建一个包含public void update(ObservableEvent oe)
方法的Observer接口和一个ObserverEvent接口。之后,您可以为每个活动创建特定的课程。
答案 2 :(得分:0)
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Observer.html
http://www.java2s.com/Code/Java/Design-Pattern/Observableandobserver.htm
Java Observer的update方法具有Object参数。您可以传递任何Object,因此您可以创建自己的“UpdateMessage”对象,该对象可以包含更新的对象以及有关所发生事件(已删除,已保存等)的其他信息。