观察者模式

设计模式之简单讨论

观察者模式(行为模式)

在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。  例如看小说读者关注作者  作者有新书时会推荐给对应的读者

1通俗来讲

其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

4个角色:

Subject(目标):被观察。维护观察者集合(增删),定义通知观察者方法notify()

ConcreteSubject(具体目标):包含经常发生改变的数据,变化时,触发notify所有观察者。

Observer(观察者):接口声明update()更新方法

ConcreteObserver(具体观察者):维护一个指向具体目标对象的引用,存储关心的数据,当具体目标数据变化时触发update(),更新数据以保持和目标数据一致。

 

 

 

 

由于观察者模式被多次使用, JDK源码就封装在rt.jar里面的java.util包下面

 

2Observer接口

观察者,声明了一个update接口,当观察Observable的子类发生变化时,调用notifyObservers方法通知观察者,执行具体观察者实现类中的update方法。

3Observable

被观察者,用Vector集合来存储观察者。

封装方法:增加、删除观察者、维护是否变化、通知观察者。(值得一提的是这些方法全部用synchronized修饰解决了并发脏数据问题

 

 

4:代码如下(idea有示例

 

观察者

package test.template.observer;
import java.util.Observable;
import java.util.Observer;
public class MyObserver implements Observer {

       private String name;
       public MyObserver(Observable o, String name) {
           o.addObserver(this); //注册机制
           this.name = name;
       }

       @Override
       public void update(Observable o, Object arg) {
           System.out.println("观察者" + name + "触发更新!arg=" + arg + ",目标的观察者数量=" + o.countObservers());
             }

        }

 

被观察者

package test.template.observer;

import java.util.Observable;

public class MyObserverable extends Observable {
    //被观察者初始数据
    private String data = "data0";

     public String getData() {
         return data;
     }

    public void setData(String data) {
         //如果数据变化了
         if (!this.data.equals(data)) {
             this.data = data;
             setChanged();//置变化状态为true
         }
         //请注意此处会存在不通知的场景  即状态未改变时
        notifyObservers(data);//通知所有观察者
     }

 }

测试

package test.template.observer;
 public class MyTest {
     public static void main(String[] args) {
         //构造被观察者
         MyObserverable observerable = new MyObserverable();
         //构造2个观察者实现类:添加观察者进观察目标
         MyObserver observer1 = new MyObserver(observerable, "1");
         MyObserver observer2 = new MyObserver(observerable, "2");
         System.out.println("===1.目标初始值=" + observerable.getData());
         System.out.println("===2.给目标设置不同值[data1],看观察者是否触发更新!==========");
         //设置目标值
         observerable.setData("data1");
         System.out.println("===3.给目标设置想同值[data1],看观察者是否触发更新!==========");
         //设置目标相同值
         observerable.setData("data1");
     }
 }

5:总结

1.优点

1)把被观察者和观察者之间建立一个抽象的耦合, 被观察者只需要维护观察者集合即可,并不依赖于观察者。

2满足开闭原则,新增观察者无需修改观察代码

3)支持广播通信,观察目标会通知所有观察者。实现了1对多通信。

2.缺点

1)如果观察者过多,会影响被观察者的性能。因为需要通知所有观察者。

2)观察模式不可滥用,过多导致程序逻辑复杂,分析问题难度增加。

3.适用场景

一个对象的改变导致其它一个或者多个对象也发生改变,且并不知道有多少个对象需要发生改变

 

posted @ 2020-09-08 18:42  春意了无痕  阅读(142)  评论(0)    收藏  举报