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中监听器就使用的是观察者模式

      

  • 相关阅读:
    夯实Java基础系列23:一文读懂继承、封装、多态的底层实现原理
    夯实Java基础系列22:一文读懂Java序列化和反序列化
    夯实Java基础系列21:Java8新特性终极指南
    夯实Java基础系列20:从IDE的实现原理聊起,谈谈那些年我们用过的Java命令
    FireDAC的SQLite初探
    delphi7 TRichView 安装
    Delphi7 GDI+学习
    Delphi7画好看的箭头线
    python swap
    pycharm **教程 大家快激活吧
  • 原文地址:https://www.cnblogs.com/javabg/p/7443399.html
Copyright © 2011-2022 走看看