java观察者模式实现和java观察者模式演化

简单的观察者模式实现

代码如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * 观察者模式中用到了回调:
 * A. 观察者将自己注册到被观察者的监听者列表,且观察者类自身提供了一个回调函数
 * B. 被观察者(Observable或Subject)维护观察者列表,并且可以注册和解注册观察者
 * C. 一旦被观察者状态发生改变,它可以调用notifyObservers(),这个方法将遍历观察者列表并逐个调用
观察者提供的回调函数
 * @author will
 *
 */
public class SimpleObserverPattern {

public static void main(String[] args) {
  SimpleObserverPattern sop = new SimpleObserverPattern();

List<IObserver> observers = new ArrayList<IObserver> ();
  IObserver observerA = sop.new Observer("ObserverA");
  IObserver observerB = sop.new Observer("ObserverB");
  observers.add(observerA);
  observers.add(observerB);

IObservable observable = sop.new Observable(observers);
  observable.registerObserver(sop.new Observer("ObserverC"));

observable.changeState();
  observable.close();
 }

// 被观察者,有的地方叫Subject
 interface IObservable {
  void registerObserver(IObserver observer);
  void unregisterObserver(IObserver observer);
  void notifyObservers();
  String getState();
  void changeState();
  void close();
 }

class Observable implements IObservable {

private static final String NEW = "New";
  private static final String CHANGED = "Changed";
  private static final String CLOSED = "Closed";

private String state;
  private List<IObserver> observers;

public Observable() {
   this(null);
  }

public Observable(List<IObserver> observers) {
   if(observers == null) {
    observers = new ArrayList<IObserver> ();
   }
    this.observers = Collections.synchronizedList(observers);
    this.state = NEW;
  }

@Override
  public void registerObserver(IObserver observer) {
   observers.add(observer);
  }

@Override
  public void unregisterObserver(IObserver observer) {
   observers.remove(observer);
  }

@Override
  public void notifyObservers() {
   Iterator<IObserver> iter = observers.iterator();
   while(iter.hasNext()) {
    iter.next().update(this);
   }
  }

@Override
  public String getState() {
   return state;
  }

@Override
  public void changeState() {
   this.state = CHANGED;
   notifyObservers();
  }

@Override
  public void close() {
   this.state = CLOSED;
   notifyObservers();
  }
 }

interface IObserver {
  void update(IObservable observalbe);
 }

class Observer implements IObserver {

private String name;

public Observer(String name) {
   this.name = name;
  }

@Override
  public void update(IObservable observalbe) {
   System.out.println(
     String.format("%s receive observalbe's change, current observalbe's state is %s",
        name, observalbe.getState()));
  }

}

}

上面的实现直接将被观察者对象作为回调函数参数,这样做很不优雅,在简单的场景可能奏效。
但事实上更多情况下,一个被观察者有很多种事件或者状态,而每个观察者可能感兴趣的事件或状态都不相同,或者为了信息隐藏的目的,不想让每个观察者都能访问到Observable内部的所有状态。
这样我继续演化代码为下面这个版本,注意我这里没有很细致地考虑并发问题。

代码如下:

import java.util.Collections;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

public class MultiEventObserverPattern {

public static void main(String[] args) {
  MultiEventObserverPattern meop = new MultiEventObserverPattern();

IObservable observable = meop.new Observable();

IObserver observerA = meop.new Observer("ObserverA");
  IObserver observerB = meop.new Observer("ObserverB");

// 注册感兴趣的事件
  observable.registerObserver(observable.getEventA(), observerA);
  observable.registerObserver(observable.getEventB(), observerB);

// 改变被观察者状态
  observable.changeStateA();
  observable.changeStateB();
 }

interface IEvent {
  void eventChange();
  String getState();
 }

class EventA implements IEvent {

private static final String INITIALIZED = "Initialized";
  private static final String PENDING = "Pending";

private String state;

public EventA() {
   this.state = INITIALIZED;
  }

@Override
  public void eventChange() {
   System.out.println("EventA change");
   this.state = PENDING;
  }

@Override
  public String toString() {
   return "EventA";
  }

@Override
  public String getState() {
   return state;
  }

}

class EventB implements IEvent {

private static final String NEW = "New";
  private static final String IDLE = "Idle";

private String state;

public EventB() {
   this.state = NEW;
  }

@Override
  public void eventChange() {
   System.out.println("EventB change");
   this.state = IDLE;
  }

@Override
  public String toString() {
   return "EventB";
  }

@Override
  public String getState() {
   return state;
  }
 }

// 被观察者(Observable),有的地方叫Subject
 interface IObservable {
  void registerObserver(IEvent event, IObserver observer);
  void unregisterObserver(IEvent event, IObserver observer);
  // 通知观察者某个事件发生了
  void notifyObservers(IEvent event);

void changeStateA();
  void changeStateB();

IEvent getEventA();
  IEvent getEventB();
 }

class Observable implements IObservable {

private IEvent eventA;
  private IEvent eventB;

private Hashtable<IEvent, Set<IObserver>> eventObserverMapping;

public Observable() {
   this(null);
  }

// 这里如果evenObserverMapping传入的某些Set<IObserver>是未被同步修饰的,那么也没办法
  public Observable(Hashtable<IEvent, Set<IObserver>> eventObserverMapping) {
   if(eventObserverMapping == null) {
    eventObserverMapping = new Hashtable<IEvent, Set<IObserver>> ();
   }
   this.eventObserverMapping = new Hashtable<IEvent, Set<IObserver>> ();

this.eventA = new EventA();
   this.eventB = new EventB();
  }

@Override
  public void registerObserver(IEvent event, IObserver observer) {
   Set<IObserver> observers = eventObserverMapping.get(event);
   if(observers == null) {
    observers = Collections.synchronizedSet(new HashSet<IObserver> ());
    observers.add(observer);
    eventObserverMapping.put(event, observers);
   }
   else {
    observers.add(observer);
   }
  }

@Override
  public void unregisterObserver(IEvent event, IObserver observer) {
   Set<IObserver> observers = eventObserverMapping.get(event);
   if(observers != null) {
    observers.remove(observer);
   }
  }

@Override
  public void notifyObservers(IEvent event) {
   Set<IObserver> observers = eventObserverMapping.get(event);
   if(observers != null && observers.size() > 0) {
    Iterator<IObserver> iter = observers.iterator();
    while(iter.hasNext()) {
     iter.next().update(event);
    }
   }
  }

@Override
  public void changeStateA() {
   // 改变状态A会触发事件A
   eventA.eventChange();
   notifyObservers(eventA);
  }

@Override
  public void changeStateB() {
   // 改变状态B会触发事件B
   eventB.eventChange();
   notifyObservers(eventB);
  }

@Override
  public IEvent getEventA() {
   return eventA;
  }

@Override
  public IEvent getEventB() {
   return eventB;
  }

}

interface IObserver {
  void update(IEvent event);
 }

class Observer implements IObserver {

private String name;

public Observer(String name) {
   this.name = name;
  }

@Override
  public void update(IEvent event) {
   System.out.println(
     String.format("%s receive %s's change, current observalbe's state is %s",
        name, event, event.getState()));
  }

}

}

似乎看起来挺完美了,但还是不够完美。因为事件被硬编码为被观察者类的属性。这样事件类型在编译时期就被定死了,如果要增加新的事件类型就不得不修改IObservable接口和Observable类,这大大削减了灵活性。
相当于被观察者耦合于这些具体的事件,那么我们如何来打破这个限制呢?
答案是引入一个新的组件,让那个组件来管理事件、观察者、被观察者之间的关系,事件发生时也由那个组件来调用观察者的回调函数。这也是一种解耦吧,有点类似Spring的IOC容器。
至于具体实现,我觉得Guava EventBus做得已经蛮好了,可以参考我前面提到的链接。

PS:本帖不是为Guava EventBus做广告,只是自己的思路一步步推进,逐渐地就和Guava EventBus的设计思路吻合了。

下面继续看看JDK标准类实现观察者模式的例子,然后分析下它的源码实现,要看的只有一个Observable类和一个Observer接口。

JDK标准类实现观察者模式

代码如下:

import java.util.Observable;
import java.util.Observer;

/**
 * 使用java.util包中的标准类实现观察者模式
 * @author will
 *
 */
public class JDKObserverDemo {

public static void main(String[] args) {
  JDKObserverDemo jod = new JDKObserverDemo();

// 被观察者
  MyObservable myObservable = jod.new MyObservable("hello");
  // 观察者
  Observer myObserver = jod.new MyObserver();
  // 注册
  myObservable.addObserver(myObserver);
  // 改变被观察者状态,触发观察者回调函数
  myObservable.setValue("will");
 }

class MyObservable extends Observable {

private String watchedValue;   // 被观察的值

public MyObservable(String watchedValue) {
   this.watchedValue = watchedValue;
  }

public void setValue(String newValue) {
   if(!watchedValue.equals(newValue)) {
    watchedValue = newValue;

setChanged();
    notifyObservers(newValue);
   }
  }

@Override
  public String toString() {
   return "MyObservable";
  }

}

class MyObserver implements Observer {

@Override
  public void update(Observable o, Object arg) {
   System.out.println(o + "'s state changed, argument is: " + arg);
  }

}

}

看了下JDK标准库中的Observer和Observable实现很简单,不想多说了。
下面是Quartz中的监听器实现。

QuartzScheduler被监听者

代码如下:

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Quartz核心类,相当于Observable(被观察者)
 * @author will
 *
 */
public class QuartzScheduler {

private ArrayList<SchedulerListener> internalSchedulerListeners = new ArrayList<SchedulerListener>(10);
// private ArrayList<JobListener> interanlJobListeners = new ArrayList<JobListener>();   // 一个Observable可以包含多组监听器

public Date scheduleJob(Trigger trigger) {
  if(trigger == null) {
   return null;
  }

System.out.println("Schedule job, trigger: " + trigger);

notifySchedulerListenersScheduled(trigger);

return new Date();
 }

public void unScheduleJob(Trigger trigger) {
  if(trigger == null) {
   return;
  }

System.out.println("Unschedule job, trigger: " + trigger);

notifyShedulerListenerUnScheduled(trigger);
 }

// 注册SchedulerListener
    public void addInternalSchedulerListener(SchedulerListener schedulerListener) {
        synchronized (internalSchedulerListeners) {
            internalSchedulerListeners.add(schedulerListener);
        }
    }

// 移除SchedulerListener
    public boolean removeInternalSchedulerListener(SchedulerListener schedulerListener) {
        synchronized (internalSchedulerListeners) {
            return internalSchedulerListeners.remove(schedulerListener);
        }
    }

public List<SchedulerListener> getInternalSchedulerListeners() {
        synchronized (internalSchedulerListeners) {
            return java.util.Collections.unmodifiableList(new ArrayList<SchedulerListener>(internalSchedulerListeners));
        }
    }

public void notifySchedulerListenersScheduled(Trigger trigger) {
     for(SchedulerListener listener: getInternalSchedulerListeners()) {
      listener.jobScheduled(trigger);
     }
    }

public void notifyShedulerListenerUnScheduled(Trigger trigger) {
     for(SchedulerListener listener: getInternalSchedulerListeners()) {
      listener.jobUnScheduled(trigger);
     }
    }

}

SchedulerListener


代码如下:

// 监听接口,回调函数,Client注册监听时需要提供回调函数实现
public interface SchedulerListener {

void jobScheduled(Trigger trigger);

void jobUnScheduled(Trigger trigger);

}

Trigger


代码如下:

// Trigger
public class Trigger {
 private String triggerKey;
 private String triggerName;

public Trigger(String triggerKey, String triggerName) {
  this.triggerKey = triggerKey;
  this.triggerName = triggerName;
 }

public String getTriggerKey() {
  return triggerKey;
 }
 public void setTriggerKey(String triggerKey) {
  this.triggerKey = triggerKey;
 }
 public String getTriggerName() {
  return triggerName;
 }
 public void setTriggerName(String triggerName) {
  this.triggerName = triggerName;
 }

public String toString() {
  return String.format("{triggerKey: %s, triggerName: %s}", triggerKey, triggerName);
 }

}

Test


代码如下:

public class Test {

public static void main(String[] args) {
  QuartzScheduler qs = new QuartzScheduler();

SchedulerListener listenerA = new SchedulerListener() {

@Override
   public void jobUnScheduled(Trigger trigger) {
    System.out.println("listenerA job unscheduled: " + trigger.getTriggerName());
   }

@Override
   public void jobScheduled(Trigger trigger) {
    System.out.println("listenerA job scheduled: " + trigger.getTriggerName());
   }
  };
  SchedulerListener listenerB = new SchedulerListener() {

@Override
   public void jobUnScheduled(Trigger trigger) {
    System.out.println("listenerB job unscheduled: " + trigger.getTriggerName());
   }

@Override
   public void jobScheduled(Trigger trigger) {
    System.out.println("listenerB job scheduled: " + trigger.getTriggerName());
   }
  };

// 注册Scheduler Listener
  qs.addInternalSchedulerListener(listenerA);
  qs.addInternalSchedulerListener(listenerB);

Trigger triggerA = new Trigger("Key1", "triggerA");
  Trigger triggerB = new Trigger("Key2", "triggerB");
  qs.scheduleJob(triggerA);
  qs.scheduleJob(triggerB);
  qs.unScheduleJob(triggerA);
 }

}

(0)

相关推荐

  • 实例解析观察者模式及其在Java设计模式开发中的运用

    一.观察者模式(Observer)的定义: 观察者模式又称为订阅-发布模式,在此模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来事件处理系统. 1.观察者模式的一般结构 首先看下观察者模式的类图描述: 观察者模式的角色如下: Subject(抽象主题接口):定义了主题类中对观察者列表的一系列操作, 包括增加,删除, 通知等. Concrete Subject(具体主题类): Observer(抽象

  • Java观察者模式例子

    观察者模式是一种行为设计模式.观察者模式的用途是,当你对一个对象的状态感兴趣,希望在它每次发生变化时获得通知.在观察者模式中,观察另外一个对象状态的对象叫做Observer观察者,被观察的对象叫着Subject被观察者. 观察者模式 Observer 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己. 观察者模式的组成 抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角

  • Java中的观察者模式实例讲解

    观察者模式是一种行为设计模式.观察者模式的用途是,当你对一个对象的状态感兴趣,希望在它每次发生变化时获得通知.在观察者模式中,观察另外一个对象状态的对象叫做Observer观察者,被观察的对象叫着Subject被观察者.根据GoF规则,观察者模式的意图是: 复制代码 代码如下: 定义对象之间一对多的依赖关系,一个对象状态改变,其他相关联的对象就会得到通知并被自动更新. Subject(被观察者)包含了一些需要在其状态改变时通知的观察者.因此,他应该提供给观察者可以register(注册)自己和u

  • Java设计模式之工厂模式(Factory模式)介绍

    工厂模式定义:提供创建对象的接口. 为何使用工厂模式 工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见. 为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量. 我们以类Sample为例,

  • 详解设计模式中的proxy代理模式及在Java程序中的实现

    一.代理模式定义 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象. 著名的代理模式的例子就是引用计数(reference counting): 当需要一个复杂对象的多份副本时, 代理模式可以结合享元模式以减少存储器的用量.典型做法是创建一个复杂对象以及多个代理者, 每个代理者会引用到原本的对象.而作用在代理者的运算会转送到原本对象.一旦所有的代理者都不存在时, 复杂对象会被移除. 要理解代理模式很简单,其实生活当中就存在代理

  • Java设计模式之观察者模式(Observer模式)介绍

    Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Observer(观察者)模式是比较常用的一个模式,尤其在界面设计中应用广泛,而本教程所关注的是Java在电子商务系统中应用,因此想从电子商务实例中分析Observer的应用. 虽然网上商店形式多样,每个站点有自己的特色,但也有其一般的共性,单就"

  • Java编程之内置观察者模式实例详解

    本文实例讲述了Java内置观察者模式.分享给大家供大家参考,具体如下: 之前也简单地写过观察者模式(又称为发布-订阅模式)小例子,现在项目中也常用到该模式.今天贴一下如何使用Java内置的观察者模式. 主要使用到的Java API就两个类: Observer接口:观察者对象,监听被观察者对象数据变化,一是数据发生变化 ,就做出相应地啥响应. Observable类:被观察者对象,提供添加及移出观察者对像方法,数据发生哟完成时并通知所有已经添加进来的观察者对象. 被观察者代码示例: //Obser

  • Java设计模式之装饰者模式详解和代码实例

    装饰者模式可以给已经存在的对象动态的添加能力.下面,我将会用一个简单的例子来演示一下如何在程序当中使用装饰者模式. 1.装饰者模式 让我们来假设一下,你正在寻找一个女朋友.有很多来自不同国家的女孩,比如:美国,中国,日本,法国等等,他们每个人都有不一样的个性和兴趣爱好,如果需要在程序当中模拟这么一种情况的话,假设每一个女孩就是一个Java类的话,那么就会有成千上万的类,这样子就会造成类的膨胀,而且这样的设计的可扩展性会比较差.因为如果我们需要一个新的女孩,就需要创建一个新的Java类,这实际上也

  • Java设计模式开发中使用观察者模式的实例教程

    观察者模式是软件设计模式中的一种,使用也比较普遍,尤其是在GUI编程中.关于设计模式的文章,网络上写的都比较多,而且很多文章写的也不错,虽然说有一种重复早轮子的嫌疑,但此轮子非彼轮子,侧重点不同,思路也不同,讲述方式也不近相同. 关键要素 主题: 主题是观察者观察的对象,一个主题必须具备下面三个特征. 持有监听的观察者的引用 支持增加和删除观察者 主题状态改变,通知观察者 观察者: 当主题发生变化,收到通知进行具体的处理是观察者必须具备的特征. 为什么要用这种模式 这里举一个例子来说明,牛奶送奶

  • Java设计模式之责任链模式(Chain of Responsibility模式)介绍

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request.也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去. 如何使用责任链模式 虽然这一段是如何使用CoR,但是也是演示什么是CoR. 有一个Handler接口: 复制代码

  • Java设计模式之模板模式(Template模式)介绍

    Template模式定义:定义一个操作中算法的骨架,将一些步骤的执行延迟到其子类中. 其实Java的抽象类本来就是Template模式,因此使用很普遍.而且很容易理解和使用,我们直接以示例开始: 复制代码 代码如下: public abstract class Benchmark { /** * 下面操作是我们希望在子类中完成 */ public abstract void benchmark(); /** * 重复执行benchmark次数 */ public final long repea

随机推荐