无法使观察者模式正常工作 [英] Having trouble getting the observer pattern working
问题描述
我一直试图使观察者模式在相对简单的应用程序中工作而无济于事.
I have been trying to no avail to get the observer pattern working in a relatively simple application.
我有4个GUI类
- StarterClass (包含
CompositeWordLists
和CompositeWordListData
) - CompositeWordLists (包含许多
CompositeListItem
/s和一个CompositeWordListData
)- CompositeListItem
- StarterClass (contains a
CompositeWordLists
and aCompositeWordListData
) - CompositeWordLists (contains many
CompositeListItem
/s and aCompositeWordListData
)- CompositeListItem
- DialogWordData
这是我的观察
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); } }
基本上,我在指定发生的事件类型时遇到了麻烦.例如,
CompositeWordLists
类需要知道什么时候删除CompositeListItem
,保存已编辑的内容等,但是我只有一种更新方法……我的大脑现在很痛!Basically I am having trouble with specifying the sort of event that occurred. For example, the
CompositeWordLists
class needs to know when aCompositeListItem
is deleted, saved edited etc but I only have one update method ... my brain hurts now!有什么更好的方法?
仍然遇到麻烦,我添加了事件并更改了Observable和Observers,但是现在我遇到类型安全问题.
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); }
问题是,当我实现此功能时,我将不得不将K强制转换为适当的类型,而不是我真正想做的.
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); }
我在做什么错了?
实际上,使用这样的Observable效果更好,但是我仍然需要在两个不同的地方指定正确的EventType.
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); }
示例事件:
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> {}
及其实现
public class ConcreteWordListObserverA implements WordListObserver { @Override public void notify(WordListUpateEvent event) { System.out.println("update item at index: " + event.getChangedIndex()); } }
另一方面,您需要您的Observable接口,为了将notifyObservers方法对观察者不公开(我将在以后看到),我将其分为两个接口:
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(); }
如果一个主题中将有多个可观察对象,则不能将Observalbe接口直接指向您的主题,因此您需要一个单独的实现类:
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(); } }
这篇关于无法使观察者模式正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!