观察者模式

Posted dearnotes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式相关的知识,希望对你有一定的参考价值。

定义

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

例:我们以新闻机构接收到新闻而后通知各个频道为例。那么新闻机构就是被观察对象,各个频道就是观察者。

实现方式

1、一般模式

① 创建Subject类
public class Subject {
   
   private List<Observer> observers 
      = new ArrayList<Observer>();
   private int state;
 
   public int getState() {
      return state;
   }
 
   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }
 
   public void attach(Observer observer){
      observers.add(observer);      
   }
 
   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   }  
}
② 创建Observer类
public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}
③ 创建实体观察者类
public class BinaryObserver extends Observer{
 
   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
      System.out.println( "Binary String: " 
      + Integer.toBinaryString( subject.getState() ) ); 
   }
}
public class OctalObserver extends Observer{
 
   public OctalObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
     System.out.println( "Octal String: " 
     + Integer.toOctalString( subject.getState() ) ); 
   }
}
④ 主方法
public class ObserverPatternDemo {
   public static void main(String[] args) {
      Subject subject = new Subject();
 
      new OctalObserver(subject);
      new BinaryObserver(subject);
 
      System.out.println("First state change: 15");   
      subject.setState(15);
      System.out.println("Second state change: 10");  
      subject.setState(10);
   }
}
⑤ 运行结果
First state change: 15
Octal String: 17
Binary String: 1111
Second state change: 10
Octal String: 12
Binary String: 1010

这个例子是参考菜鸟教程,总结得很详细。

2、实现PropertyChangeListener接口

① 创建被观察者
public class Subject {
     private int state;
     private String message="0";
     private PropertyChangeSupport support;
     
     public Subject() {
        // TODO Auto-generated constructor stub
         support=new PropertyChangeSupport(this);
    }
     public int getState() {
          return state;
       }
     
       public void setState(int state) {
          this.state = state;  
         
          notifyTo(String.valueOf(state));
       }
       
       public void addPropertyChangeListener(PropertyChangeListener pcl) {
           support.addPropertyChangeListener(pcl);
       }
       
       public void removePropertyChangeListener(PropertyChangeListener pcl) {
           support.removePropertyChangeListener(pcl);
       }
       
       public void notifyTo(String value) {
           support.firePropertyChange("",message,value);
           
           
       }
     
     
}
② 创建观察者
public class BinaryObserver implements PropertyChangeListener {
    
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        // TODO Auto-generated method stub
         System.out.println( "值更新为 "+evt.getNewValue()); 
        
    }
}
③ 主方法
public class MyObserver {
    public static void main(String[] args) {
        Subject subject=new Subject();
        BinaryObserver binaryObserver=new BinaryObserver();
        
        subject.addPropertyChangeListener(binaryObserver);
        subject.setState(10);
        subject.setState(15);

    }

}
④ 运行结果
值更新为 10
值更新为 15

这个观察者类就写了一个,懒得写第二个了。

观察者模式我们用图表达出来就是这个样子的

技术图片

很形象吧!

应用场景

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  • 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要被改变。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,不希望这些对象是紧密耦合的。

就像报社和订报纸的人
发Email给用户

优缺点

优点
观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。

缺点
在应用观察者模式时需要考虑一下开发小路问题,程序中包括一个被观察者和多个被观察者,开发和调试比较复杂,而且Java中的消息的通知默认是顺序执行的,一个观察者的卡顿会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。 [2]

以上是关于观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

未调用 LiveData 观察者

Java设计模式补充:回调模式事件监听器模式观察者模式(转)

如何为片段设置观察者

永远观察实时数据的片段

设计模式观察者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

观察者模式