美文网首页
设计模式之观察者模式

设计模式之观察者模式

作者: bpker | 来源:发表于2019-08-10 22:26 被阅读0次

      观察者模式定义对象一对多的关系,他希望一个对象的状态发生改变时,其他依赖于它的对象能够接到通知并执行相应的处理逻辑。例如微信订阅某个公众号,当公众号发布新文章时,所有订阅该公众号的人都会收到文章推送消息。spring的事件机制是采用观察者模式,进行业务的解耦的。
       观察模式简单分为被观察者和观察者,实现原理为被观察者有一个存放观察者的集合,当被观察者发生状态改变时,通知所有的观察者,观察者处理相应的逻辑。

    被观察者

       这里简单用一个类来描述被观察者,它可以接收观察者类型,和更新状态,当状态更新时,会通知所有观察者的onMessage()方法,处理相应的逻辑。

    
    import java.util.ArrayList;
    import java.util.List;
    
    @Data
    public class Subject {
        private List<Observer> observers = new ArrayList<Observer>();
    
        public void update(){
            notifyObervers();
        }
        
        public void addObserver(Observer observer) {
            observers.add(observer);
        }
        
        private void notifyObervers(){
            for (Observer observer: observers) {
                observer.onMessage();
            }
        }
    }
    

    观察者

    这里定义观察者,它有一个指定具体名称的构造方法,和一个onMessage()方法,在被观察者状态发生改变时被调用

    import lombok.Data;
    
    @Data
    public class Observer{
        private String name;
    
        public Observer(String name) {
            this.name = name;
        }
    
        public void onMessage() {
            System.out.println(name + "监听到发布事件");
        }
    }
    

    客户端

    当我们定义好了被观察者和观察者,使用一个类来模拟相应的测试流程。
    这里定义了一个被观察者和两个观察者,然后被观察者更新状态,那么其他的观察者就会接到通知,然后处理事件。

    public class App {
        public static void main(String[] args) {
            Subject subject = new Subject();
    
            Observer firstObserver = new Observer("firstObserver");
            Observer secondObserver = new Observer("secondObserver");
            subject.addObserver(firstObserver);
            subject.addObserver(secondObserver);
    
            subject.update();
        }
    }
    
    输出
    firstObserver监听到发布事件
    secondObserver监听到发布事件
    

    升级版本

    考虑到被观察者进行状态更新时,不需要通知所有观察者进行状态更新,而是只需要关注它的状态更新的观察者才需要接到通知。

    观察者

    我们先来定义观察者的逻辑,这里通过泛型,来定义观察者只关注具体的被观察者的实现。

    import lombok.Data;
    
    @Data
    public class Observer<T extends Subject>{
        private String name;
    
        private T subject;
    
        public Observer (String name, T subject) {
            this.name = name;
            this.subject = subject;
            subject.addObserver(this);
        }
    
        public void onMessage() {
            System.out.println(this.name + "监听到事件");
        }
    }
    

    被观察者

    被观察的notifyObervers()方法,在通知观察者进行状态更新时,只有该观察者关注的是自己的实现时,才更新。

    import java.util.ArrayList;
    import java.util.List;
    
    @Data
    public class Subject {
    
        private List<Observer> observers = new ArrayList<Observer>();
    
        public void addObserver(Observer observer) {
            observers.add(observer);
        }
    
        public void update(){
            notifyObervers();
        }
    
        public void notifyObervers(){
            for (Observer observer: observers) {
                if (observer.getSubject().getClass() == this.getClass()) {
                    observer.onMessage();
                }
            }
        }
    }
    

    我们这里定义两个被观察者的实现类。

    public class FirstSubject extends Subject {}
    
    public class SecondSubject extends Subject {}
    

    客户端

    这里客户端的使用代码为,实例化了一个FirstSubject对象和一个SecondSubject。和两个Observer对象,他们都只关注各自的Subject。在把secondObserver也加到firstSubject对象的观察者集合里面,这时

    public class App {
        public static void main(String[] args) {
            Subject firstSubject = new FirstSubject();
            Subject secondSubject = new SecondSubject();
    
            Observer<FirstSubject> firstObserver = new Observer<FirstSubject>("firstObserver", (FirstSubject) firstSubject);
            Observer<SecondSubject> secondObserver = new Observer<SecondSubject>("secondObserver", (SecondSubject) secondSubject);
    
            firstSubject.addObserver(secondObserver);
    
            firstSubject.update();
        }
    }
    
    输出
    firstObserver监听到事件
    

    这样就实现了一个泛型类的观察者,这里的实现感觉有些蹩脚,还需要看看别人时怎么实现的。

    相关文章

      网友评论

          本文标题:设计模式之观察者模式

          本文链接:https://www.haomeiwen.com/subject/nomdjctx.html