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

标签 java observer-pattern

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

我有 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/

    相关文章:

    java - WordNet 相似之处 java

    java - 销毁的 jdbc 连接数和释放回池的连接数有什么区别吗?

    java - 在java中将整数转换为字符串的最快方法

    android - 从数据库中成功检索数据但无法通过适配器类

    java - JOOQ json 绑定(bind)问题

    java - 请求的资源不可用 Java REST API

    javascript - 在json中传递函数并执行

    spring - 如何为 REST API 实现观察者模式?

    c# - .Net 观察者模式改变。这些是什么时候发生的,为什么?

    ruby-on-rails - Rails 3 Observer——希望学习如何为多个模型实现一个观察者