Chinaunix首页 | 论坛 | 博客
  • 博客访问: 202645
  • 博文数量: 69
  • 博客积分: 2946
  • 博客等级: 少校
  • 技术积分: 800
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-09 04:15
文章分类

全部博文(69)

文章存档

2013年(6)

2012年(16)

2011年(18)

2010年(29)

分类: Java

2013-02-27 21:59:27

观察者模式定义了一种一对多的一种关系,在这种模式中,被观察者一般只有一个,而对被观察者进行观察的观察者通常有多个。观察者在被观察者处订阅或者注册之后,被观察者得的状态如果有更新,将给在被观察者处注册的所有观察者发送通知。这是一种广播的关系,不管观察者对当时被观察者状态的改变是否关心。

 image

图.1

image

图.2

抽象被观察者,将所有观察者添加到一个聚合里(Vector,Enumeration),拥有添加、删除观察者的方法,提供了一个借口,被具体被观察者所继承或者实现,一般用借口或者抽象类来充当该角色,在JDK中有Observable.

被观察者,继承或者实现抽象被观察者。其内部状态发生改变时,会通知订阅了的观察者。该角色通常由一个具体的类来充当.

抽象观察者,定义了一个观察者都继承或者实现的一个接口。在改接口中,定义了一个update的方法,主要用来更新观察者的状态信息,包括从被观察者获取相关信息。一般由接口或者抽象类来充当。

具体观察者,实现了抽象观察这所定义的更新方法,具体观察者自身保有跟被观察者相关的属性。在某种情况下,更新方法能够获取具体被观察者的引用。

下面给出上结构图观察者模式的简单代码:

被观察者代码:

1:  public interface AbstractObservable {          //抽象被观察者,由接口来充当
2:   
3:      public void add(AbstractObserver observer);
4:      public void delete(AbstractObserver observer);
5:      public void notifyObservers();
6:  }

具体被观察者:

 1:  public class ConcreteObservable implements AbstractObservable { //具体被观察者
 2:   
 3:      private int state;
 4:      private Vector observers = new Vector();
 5:   
 6:      public void add(AbstractObserver observer) {
 7:          observers.add(observer);
 8:      }
 9:      public void delete(AbstractObserver observer) {
10:          observers.remove(observer);
11:      }
12:      public void notifyObservers() {
13:          Iterator it = observers.iterator();
14:          while(it.hasNext()){
15:              AbstractObserver observer = (AbstractObserver)it.next();
16:              observer.update();
17:          }
18:      }
19:      public void modifyState(int s){
20:          this.state = s;
21:          notifyObservers();
22:      }
23:  }

抽象观察者

1:  public interface AbstractObserver {
2:   
3:      public void update();
4:  }

具体观察者

1:  public class ConcreteObserver implements AbstractObserver {
2:   
3:      public void update() {
4:          System.out.println("Status update!");
5:      }
6:  }

上面代码的示例是对图1的简单实现。从图2中可以知道,抽象被观察者自身具有所有订阅了的观察者的聚合,在这种情况下,可以将抽象被观察者和具体被观察者两者的角色融合,由被观察者一个对象来充当,结构图如下:

image图.3

没有抽象被观察者角色。

观察者模式在JDK中给出基本的实现,所以在实际应用中,我们对抽象被观察者和抽象观察者都可以直接应用JDK中给出的接口,然后对其中的方法覆写。

image

图.4

创建两个类,分别继承自Observable和借口Observer,

 1:  public class ConObervable extends Observable {
 2:   
 3:      private int status = 0;
 4:      public int getStatus(){
 5:          return status;
 6:      }
 7:      public void changeStatus(int status){
 8:          if( this.status != status){
 9:              System.out.println(this.status + ":" + status);
10:              this.status = status;
11:              setChanged();
12:              this.notifyObservers();
13:          }
14:      }
15:  }

具体观察者:

1:  public class ConObserver implements Observer {
2:   
3:      public void update(Observable arg0, Object arg1) {
4:          System.out.println(arg0 + "get the status change info: " + arg1);
5:      }
6:  }

测试类:

 1:  public class ObserverTest {
 2:   
 3:      static ConObervable observable = null;
 4:      static Observer observer = null;
 5:      public static void main(String[] args) {
 6:   
 7:          observable = new ConObervable();
 8:          observer = new ConObserver();
 9:          observable.addObserver(observer);
10:   
11:          observable.changeStatus(0);
12:          observable.changeStatus(1);
13:          observable.changeStatus(2);
14:          observable.changeStatus(3);
15:          observable.changeStatus(4);
16:          observable.changeStatus(4);
17:      }
18:  }

运行就可以显示类状态改变所引起观察类的输出。

观察模式的优缺点

优点:
  • 观察者模式使被观察者和观察者之间的关系耦合,被观察者只保留观察者的一个聚合,且针对观察者的借口进行操作,不涉及具体的观察者。只要实现了该借口的类都能成为观察者,系统的灵活性大大提高。
  • 观察者模式是一个灵活的广播模式,在需要广播通讯的应用环境下非常适用。
缺点:
  • 被观察者在状态改变时,一般会通知所有注册过的观察者,效率不高。
  • 被观察者不管观察者对该状态改变的通知是否需要,它都会给观察者发送通知。
  • 观察者模式是对观察者而言是一种被动的形式,它不能主动实时的去获取被观察者状态。
  • 观察者虽然在被观察者状态发生改变时,能够收到通知,但是它不能获取被观察者状态发生改变的过程。
Technorati 标签: ,,
阅读(1816) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~