zoukankan      html  css  js  c++  java
  • 观察者模式

    定义

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

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

    实现方式

    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]

  • 相关阅读:
    CSS3中的3D效果
    JavaScript判断数据类型方法?
    JS函数中的arguments是什么?
    Vue组件之间通信的几种方式
    Vue插槽详解
    CSS文本溢出效果&滚动条样式设置
    Fibonacci数列计算的三种方法
    堆内存和栈内存详解[转]
    带头结点的单链表反转
    汉诺塔问题
  • 原文地址:https://www.cnblogs.com/dearnotes/p/12275050.html
Copyright © 2011-2022 走看看