gpt4 book ai didi

java - 无法让观察者模式正常工作

转载 作者:行者123 更新时间:2023-12-04 06:40:43 29 4
gpt4 key购买 nike

我一直试图让观察者模式在一个相对简单的应用程序中工作,但无济于事。

我有 4 个 GUI 类

  • 入门类 (包含 CompositeWordListsCompositeWordListData )
  • 复合词表 (包含许多 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类(class)需要知道何时 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);
    }

    我究竟做错了什么?

    更新 2

    实际上,像这样的 Observable 效果更好,但我仍然需要在两个不同的地方指定正确的 EventType。
    interface Observable<T,K> {
    void addObserver(T o);
    void removeObserver(T o);
    void removeAllObservers();
    void notifyObservers(Observers.ObservableEvent<K> e);
    }

    最佳答案

    您不需要对观察者进行参数化,但需要对事件进行参数化。

    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 接口(interface),我将其拆分为两个接口(interface),以使 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();
    }

    如果您在一个主题中有多个可观察对象,则无法将 Observalbe 接口(interface)直接实现到您的主题,因此您需要一个单独的实现类:
    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();
    }
    }

    关于java - 无法让观察者模式正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4283304/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com