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

    观察者模式又名发布-订阅模式,定义了对象之间的一对多依赖,多个对象同时监听一个对象,当被监听对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新,被监听对象称为主题suject,监听对象称为观察者observer。

    观察者模式结构如下(网上找的图):


    简单来说,observer必须实现update方法,来接收suject状态变化时的通知及更新。suject维护一个observer列表,在状态变化时会逐个的调用observer的update方法来通知、更新observer,为此,suject须提供注册(添加observer到列表)、删除、通知更新三个方法。

    观察者模式又分为两种模式:push和pull。push是指suject在状态变化时将所有的状态信息都发给observer,pull则是suject通知observer更新时,observer获取自己感兴趣的状态。

    两种模式在实现上的区别:push模式下,observer的update方法接收的是状态信息,而pull模式下,update方法接收的是suject对象,这种情况下,suject须提供状态信息的get方法,让observer可以获取自己感兴趣的信息。

    两种模式的优劣:push模式要求suject必须了解observer需要的状态,pull则是observer按需获取;push模式下observer的update方法的参数是具体的状态信息,发生变化时必须要重写update方法,pull模式则是将suject对象本身传给update,是最大的参数集合。

    push模式具体实现:

    • suject超类
      package observer.push;
      
      import java.util.LinkedList;
      import java.util.List;
      
      /**
       * 推模式主题超类,能够注册、删除、数据变动时通知关注者
       * @author sky
       *
       */
      public abstract class Subject {
      	/**
      	 * 观察者名单
      	 */
      	private List<Observer> list = new LinkedList<>();
      	/**
      	 * 注册观察者
      	 * @param o 观察者
      	 */
      	public void addObserver(Observer o){
      		list.add(o);
      	}
      	/**
      	 * 删除观察者
      	 * @param o 观察者
      	 */
      	public void deleteObserver(Observer o){
      		int i = list.indexOf(o);
      		if (i>-1) {
      			list.remove(i);
      		}
      	}
      	/**
      	 * 通知观察者
      	 */
      	public void notifyObservers(String state){
      		for (Observer o:list) {
      			o.update(state);
      		}
      	}
      }
      
    • observer接口
      package observer.push;
      /**
       * 推模式观察者接口
       * @author sky
       *
       */
      public interface Observer {
      	
      	public void update(String state);
      
      }
      
    • suject具体实现类
      package observer.push;
      
      public class ConcreteSubject extends Subject {
      	/**
      	 * 状态
      	 */
      	public String state;
      	/**
      	 * 状态是否改变的标志
      	 */
      	public boolean isChanged = false;
      	
      	/**
      	 * 状态改变后,通知观察者
      	 */
      	public void change(){
      		if (isChanged) {
      			this.notifyObservers(state);
      		}
      	}
      
      	public String getState() {
      		return state;
      	}
      
      	public void setState(String state) {
      		this.state = state;
      		isChanged = true;
      	}
      
      	public boolean isChanged() {
      		return isChanged;
      	}
      
      	public void setChanged(boolean isChanged) {
      		this.isChanged = isChanged;
      	}
      	
      	
      
      }
      


    • observ具体实现类
      package observer.push;
      /**
       * 推模式观察者实现类
       * @author sky
       *
       */
      public class ConcreteObserver implements Observer {
      	
      	public String name;
      	
      	public ConcreteObserver(String n){
      		name=n;
      	}
      
      	@Override
      	public void update(String state) {
      		System.out.println(name+" update new state:"+state);
      		
      	}
      
      }
      
    • 测试类:
      package observer.push;
      
      public class Test {
      
      	/**
      	 * @param args
      	 */
      	public static void main(String[] args) {
      		ConcreteSubject subject = new ConcreteSubject();
      		Observer o1 = new ConcreteObserver("张山");
      		Observer o2 = new ConcreteObserver("李四");
      		subject.addObserver(o1);
      		subject.addObserver(o2);
      		System.out.println("准备:");
      		subject.setState("上班了");
      		subject.change();
      		subject.setState("下班了");
      		subject.change();
      	}
      
      }
      

    • 输出:
      准备:
      张山 update new state:上班了
      李四 update new state:上班了
      张山 update new state:下班了
      李四 update new state:下班了

    pull模式实现:

    • suject超类
      package observer.pull;
      
      import java.util.LinkedList;
      import java.util.List;
      
      /**
       * 拉模式主题超类,能够注册、删除、数据变动时通知关注者
       * @author sky
       *
       */
      public abstract class Subject {
      	/**
      	 * 观察者名单
      	 */
      	private List<Observer> list = new LinkedList<>();
      	/**
      	 * 注册观察者
      	 * @param o 观察者
      	 */
      	public void addObserver(Observer o){
      		list.add(o);
      	}
      	/**
      	 * 删除观察者
      	 * @param o 观察者
      	 */
      	public void deleteObserver(Observer o){
      		int i = list.indexOf(o);
      		if (i>-1) {
      			list.remove(i);
      		}
      	}
      	/**
      	 * 通知观察者
      	 */
      	public void notifyObservers(){
      		for (Observer o:list) {
      			o.update(this);
      		}
      	}
      }
      


    • observer接口
      package observer.pull;
      /**
       * 拉模式观察者接口
       * @author sky
       *
       */
      public interface Observer {
      	
      	public void update(Subject s);
      
      }
      


    • suject具体实现类
      package observer.pull;
      
      public class ConcreteSubject extends Subject {
      	/**
      	 * 状态
      	 */
      	public String state;
      	/**
      	 * 状态是否改变的标志
      	 */
      	public boolean isChanged = false;
      	
      	/**
      	 * 状态改变后,通知观察者
      	 */
      	public void change(){
      		if (isChanged) {
      			this.notifyObservers();
      		}
      	}
      
      	public String getState() {
      		return state;
      	}
      
      	public void setState(String state) {
      		this.state = state;
      		isChanged = true;
      	}
      
      	public boolean isChanged() {
      		return isChanged;
      	}
      
      	public void setChanged(boolean isChanged) {
      		this.isChanged = isChanged;
      	}
      	
      	
      
      }
      


    • observer具体实现类
      package observer.pull;
      /**
       * 拉模式观察者实现类
       * @author sky
       *
       */
      public class ConcreteObserver implements Observer {
      	
      	public String name;
      	
      	public ConcreteObserver(String n){
      		name=n;
      	}
      
      	@Override
      	public void update(Subject s) {
      		String state = ((ConcreteSubject)s).getState();
      		System.out.println(name+" update new state:"+state);
      		
      	}
      
      
      }
      


    • 测试类
      package observer.pull;
      
      public class Test {
      
      	/**
      	 * @param args
      	 */
      	public static void main(String[] args) {
      		ConcreteSubject subject = new ConcreteSubject();
      		Observer o1 = new ConcreteObserver("张山");
      		Observer o2 = new ConcreteObserver("李四");
      		subject.addObserver(o1);
      		subject.addObserver(o2);
      		System.out.println("pull模式准备:");
      		subject.setState("上班了");
      		subject.change();
      		subject.setState("下班了");
      		subject.change();
      	}
      
      }
      


    • 输出
      pull模式准备:
      张山 update new state:上班了
      李四 update new state:上班了
      张山 update new state:下班了
      李四 update new state:下班了


  • 相关阅读:
    Java中的CopyOnWrite
    Collection和Collections的区别
    java中值类型与引用类型的关系
    Xml的用途
    js弹框的3种方法
    文件夹重定向失败解决方案
    网络管理人员经常遇到的十个问题(转载)
    QTP之下拉列表单选框…
    Windows脚本宿主对象模型
    QTP报错“缺少对象WScript”
  • 原文地址:https://www.cnblogs.com/pangblog/p/3310740.html
Copyright © 2011-2022 走看看