• 观察者模式


    定义

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

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

    实现方式

    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]

  • 相关阅读:
    bzoj-2748 2748: [HAOI2012]音量调节(dp)
    bzoj-2338 2338: [HNOI2011]数矩形(计算几何)
    bzoj-3444 3444: 最后的晚餐(组合数学)
    codeforces 709E E. Centroids(树形dp)
    codeforces 709D D. Recover the String(构造)
    codeforces 709C C. Letters Cyclic Shift(贪心)
    codeforces 709B B. Checkpoints(水题)
    codeforces 709A A. Juicer(水题)
    Repeat Number
    hdu 1003 Max Sum (动态规划)
  • 原文地址:https://www.cnblogs.com/dearnotes/p/12275050.html
Copyright © 2020-2023  润新知