zoukankan      html  css  js  c++  java
  • 设计模式系列之----观察者模式

    观察者模式是一个广播机制的基础,实现1对N的联动,当1发生变化,N跟着相应变化,由此衍生了发布订阅模式,其方式分两种,①强制推送:当1发生变化,强制N也跟着发生变化,②拉的方式,即N方可以自己决定是否接收,只有当N这方有需要时才去获取最新的,不然就算1方变化,N这方也不更新。

     观察者接口和具体实现类:

    /**
     *观察者接口
     */
    public interface Observer {
    
    	void update(Subject subject);//观察者接收一个推送过来的主题
    	
    }
    
    //============================
    
    /**
     *观察者具体实现类
     */
    public class ObserverImpl implements Observer {
    
    	private int state; //拥有与主体一致的状态,用于接收订阅的主题内容 
    	
    	public int getState() {
    		return state;
    	}
    
    	public void setState(int state) {
    		this.state = state;
    	}
    
    	@Override
    	public void update(Subject subject) {
    		this.state=((ConcreteSubject)subject).getState();//在具体观察者中进行同步状态更新
    	}
    
    }
    

    主题基类和主题具体类

    /**
     * 主体的基类,定义了一些公用方法,没有具体主题,也可以定义成抽象类
     */
    public class Subject {
    
    	public List<Observer> list=new ArrayList<Observer>();//在主体方定义一个容器存放注册的观察者
    	
    	public void registerObserver(Observer obs){
    		list.add(obs);//注册观察者,即把需要订阅的观察者加进容器中
    	}
    	
    	public void removeObserver(Observer obs){
    		list.remove(obs);//移除观察者
    	}
    	
    	//主题发生变化时,通知所有观察者进行更新
    	public void notifyAllObservers(List<Observer> list){
    		for (Observer observer : list) {
    			observer.update(this);
    		}
    	}
    	
    }
    
    //=================================================
    
    /**
     *有具体主题的子类
     */
    public class ConcreteSubject extends Subject {
    
    	private int state;//模拟一个具体主题
    
    	public int getState() {
    		return state;
    	}
    
    	public void setState(int state) {
    		this.state = state;
    		this.notifyAllObservers(list);//此步为关键,当主题发生变化时,主题中注册的观察者的状态也跟着进行更新
    	}	
    	
    }
    

    客户端调用:

    		public static void main(String[] args) {
    			
    			ConcreteSubject concreteSubject = new ConcreteSubject();//目标主题,发布者
    			
    			ObserverImpl observer1=new ObserverImpl();
    			ObserverImpl observer2=new ObserverImpl();
    			ObserverImpl observer3=new ObserverImpl();
    			
    			concreteSubject.registerObserver(observer1);//注册观察者
    			concreteSubject.registerObserver(observer2);
    			concreteSubject.registerObserver(observer3); 
    			
    			concreteSubject.setState(1000);//目标主题状态为1000
    			System.out.println(observer1.getState());
    			System.out.println(observer2.getState());
    			System.out.println(observer3.getState());//观察者的值也都为1000
    			
    			concreteSubject.setState(2000);//目标主题状态值发生改变
    			System.out.println(observer1.getState());
    			System.out.println(observer2.getState());
    			System.out.println(observer3.getState());//观察者的值也改为2000
    			
    		}
    

    以上代码是自己实现的观察者模式,实际上JavaSE中已经为我们提供了实现观察者模式的基础,java.util.Observable类和java.util.Observer接口,通过这两个对象可以方便的实现观察者模式,java.util.Observable相当于上面定义的Subject,Observable中定义好了一些常用的方法来添加观察者,移除观察者等,观察者只要实现Observer接口就具有观察者身份,可以被添加进来。  

    /**
     * 继承JDK的Observable类实现主题
     */
    public class ConcreteSubject extends Observable{
    
    	private int state;
    
    	public int getState() {
    		return state;
    	}
    
    	public void setState(int state) {
    		this.state = state;
    		super.setChanged();//当次属性发生改变时,调用基类的setChanged()方法表示当前观察者有改变,
    		                   //主要改变super.hasChanged()方法返回值,观察者可以通过此值判断目标对象是否已改变
    		super.notifyObservers(this.state);//把当前发生改变的对象通知各个观察者
    	} 
    }
    
    //===================================================
    
    /**
     *实现JDK的观察者接口,实现更新方法
     */
    public class ObserverImpl implements Observer {
    
    	private int state;	
    	
    	public int getState() {
    		return state;
    	}
    
    	public void setState(int state) {
    		this.state = state;
    	}
    
    	@Override
    	public void update(Observable o, Object obj) {
    		setState(((ConcreteSubject)o).getState());
    		//this.state =Integer.parseInt((String)obj);//也可以直接通过传递过来的参数赋值
    	}
    }
    
    //==================================================
    
    	public static void main(String[] args) {
    
    		ConcreteSubject subject=new ConcreteSubject();
    		
    		ObserverImpl observer1=new ObserverImpl();
    		ObserverImpl observer2=new ObserverImpl();
    		ObserverImpl observer3=new ObserverImpl();
    		
    		subject.addObserver(observer1);
    		subject.addObserver(observer2);
    		subject.addObserver(observer3);
    		
    		subject.setState(10);
    		
    		System.out.println(observer1.getState());
    		System.out.println(observer2.getState());
    		System.out.println(observer3.getState());//观察者的值也都为1000
    		
    		subject.setState(2000);//目标主题状态值发生改变
    		System.out.println(observer1.getState());
    		System.out.println(observer2.getState());
    		System.out.println(observer3.getState());//观察者的值也改为2000
    		
    	}
    

    JavaEE中监听器就使用的是观察者模式

      

  • 相关阅读:
    Linux三剑客之sed深度实践讲解(上)
    Linux第三阶段题型测试
    Linux正则表达式题型
    linux文本处理三剑客命令及用法
    SSH服务协议、部署ssh、scp、sftp服务
    NFS客户端挂载及永久生效
    SSH实现无密码登录
    NFS深度解析及搭建同步NFS服务
    NFS文件系统及搭建NFS共享服务
    Linux系统磁盘管理
  • 原文地址:https://www.cnblogs.com/javabg/p/7443399.html
Copyright © 2011-2022 走看看