观察者模式(Observer Pattern)

    在对象关系间定义了一个一对多的依赖关系,当一个对象改变状态时,以便于它的依赖对象能够被自动化地被告知和更新。观察者模式是属于行为型模式之一。一个对象(object)发生状态改变而做出相应的反应,这个成为Observer;相对应的,被观察者就称之为Subject。

    Java提供了通过 java.util.Observable  java.util.Observer接口实现观察者模式的构建平台。然而,它并没有被广泛使用,因为这个实现太简单,并且没有这个必要。

    Java消息服务(JMS)使用了观察者模式,伴随着中介者模式,允许应用程序订阅和发布数据到其它的应用程序中。Web开发中,流行的MVC(Model-View-Controller)框架也使用观察模式,模型(model)就是一个Subject,视图(Views)就是观察者。它通过注册到模型上,模型上任何变动都会通知视图。

     实现一个实例,UML视图如下所示:

 

 

 


     对于这个例子,我们将实现一个简单的主题,观察者注册到这个主题上。无论何时什么信息发送到这个主题上,所有它的注册者将收到这个信息,它们能够根据这个信息做相应的操作。有点像微薄信息的推送模式,认真理解了一定会发现其中的相似之处。

    主体类Subject

    public interface Subject {
 
          //methods to register and unregister observers
          public void register(Observer obj);
          public void unregister(Observer obj);
 
          //method to notify observers of change
          public void notifyObservers();
 
          //method to get updates from subject
          public Object getUpdate(Observer obj);
 
}


观察者类

public interface Observer {
 
          //method to update the observer, used by subject
          public void update();
 
          //attach with subject to observe
          public void setSubject(Subject sub);
}


我的主题信息类。

public class MyTopic implements Subject {
 
          private List<Observer> observers;
          private String message;
          private boolean changed;
          private final Object MUTEX= new Object();
 
          public MyTopic(){
                    this.observers=new ArrayList<>();
          }
          @Override
          public void register(Observer obj) {
                    if(obj == null) throw new NullPointerException("Null Observer");
                    if(!observers.contains(obj)) observers.add(obj);
          }
 
          @Override
          public void unregister(Observer obj) {
                    observers.remove(obj);
          }
 
          @Override
          public void notifyObservers() {
                    List<Observer> observersLocal = null;
                    //synchronization is used to make sure any observer registered after message is received is not notified
                    synchronized (MUTEX) {
                               if (!changed)
                                         return;
                              observersLocal = new ArrayList<>(this.observers);
                               this.changed=false;
                    }
                    for (Observer obj : observersLocal) {
                               obj.update();
                    }
 
          }
 
          @Override
          public Object getUpdate(Observer obj) {
                    return this.message;
          }
 
          //method to post message to the topic
          public void postMessage(String msg){
                    System.out.println("Message Posted to Topic:"+msg);
                    this.message=msg;
                    this.changed=true;
                    notifyObservers();
          }
 
}


定义观察者的实现类,它将绑定到这个Subject上。

public class MyTopicSubscriber implements Observer {
 
          private String name;
          private Subject topic;
 
          public MyTopicSubscriber(String nm){
                    this.name=nm;
          }
          @Override
          public void update() {
                    String msg = (String) topic.getUpdate(this);
                    if(msg == null){
                               System.out.println(name+":: No new message");
                    }else
                    System.out.println(name+":: Consuming message::"+msg);
          }
 
          @Override
          public void setSubject(Subject sub) {
                    this.topic=sub;
          }
 
}


测试类,实现如下:

public class ObserverPatternTest {
 
          public static void main(String[] args) {
                    //create subject
                    MyTopic topic = new MyTopic();
 
                    //create observers
                    Observer obj1 = new MyTopicSubscriber("Obj1");
                    Observer obj2 = new MyTopicSubscriber("Obj2");
                    Observer obj3 = new MyTopicSubscriber("Obj3");
 
                    //register observers to the subject
                    topic.register(obj1);
                    topic.register(obj2);
                    topic.register(obj3);
 
                    //attach observer to subject
                    obj1.setSubject(topic);
                    obj2.setSubject(topic);
                    obj3.setSubject(topic);
 
                    //check if any update is available
                    obj1.update();
 
                    //now send message to subject
                    topic.postMessage("New Message");
          }
 
}


输出结果:

Obj1:: No new message
Message Posted to Topic:New Message
Obj1:: Consuming message::New Message
Obj2:: Consuming message::New Message
Obj3:: Consuming message::New Message


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值