观察者模式 java MySQL_Java 设计模式中观察者模式实例教程

观察者模式又称为发布/订阅(Publish/Subscribe)模式,观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

观察者(Observer)相当于事件监听者,被观察者(Observable)相当于事件源和事件,将观察者和被观察者的对象分离开,提高了应用程序的可维护性和重用性。执行逻辑时通知observer即可触发oberver的update,同时可传被观察者和参数。

观察者Observer:所有潜在的观察者必须实现观察者接口,这个接口只有update方法,当主题改变时,它被调用。

具体观察者ConcreteObserver: 具体观察者可以是任何实现了Observer接口的类。观察者必须注册具体主题,一边接收更新。

可观察者Subject: 主题接口,即可观察者Observable,对象使用此接口注册为观察者,或者把自己从观察者中删除,每个主题可以有多个观察者。

具体可观察者ConcreteSubject: 一个具体主题实现了主题接口,除了注册和撤销之外,具体主题还实现了notifyObservers()方法,这个方法用来在主题状态改变时更新所有观察者。具体主题也可能有设置和获取状态的方法。

Subject(被观察者)包含了一些需要在其状态改变时通知的观察者。因此,他应该提供给观察者可以register(注册)自己和unregister(注销)自己的方法。当Subject(被观察者)发生变化的时候,也需要包含一个方法来通知所有观察者。当通知观察者的时候,可以推送更新内容,或者提供另外一个方法来获得更新内容。参考资料:https://www.javacodegeeks.com/2013/08/observer-design-pattern-in-java-example-tutorial.html

JAVA提供了内置的方式来实现观察者模式,java.util.Observable和java.util.Observer接口。然而他们用的不是很广泛。因为此实现过于简单,大多数时候我们都不想最后扩展的类仅仅是实现了观察者模式,因为JAVA类不能多继承。

Java Messages Service(JMS)消息服务使用观察者模式与命令模式来实现不同的程序之间的数据的发布和订阅。MVC模型-视图-控制框架也使用观察者模式,把模型当做被观察者,视图视为观察者。视图能够注册自己到模型上来获得模型的改变。

观察者模式实例

在此实例中,将完成一个简单的主题讨论,观察者能够注册此主题。任何在此主题上的内容提交导致的变化都会通知所有注册的观察者。基于Subject被观察者的需求,这个是实现一个基本的Subject接口,此接口定了一系列具体的方法需要在随后实现接口的具体类中被实现。package com.journaldev.design.observer;

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);

}

现在创建一个相关联的观察者。它需要有一个方法能使Subject附属于一个观察者。另外的方法能够接受Subject的变化通知。package com.journaldev.design.observer;

public interface Observer {

//method to update the observer, used by subject

public void update();

//attach with subject to observe

public void setSubject(Subject sub);

}

这种关联已经建立。现在实现具体的主题。package com.journaldev.design.observer;

import java.util.ArrayList;

import java.util.List;

public class MyTopic implements Subject {

private List 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 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();

}

}

注册与注销观察者方法的实现非常简单,额外的方法postMessage()将被客户端应用来提交一个字符串消息给此主题。注意,布尔变量用于追踪主题状态的变化并且通知观察者此种变化。这个变量是必须的,因为如果没有更新,但是有人调用notifyObservers()方法,他就不能发送错误的通知信息给观察者。

此外需要注意的是,notifyObservers()中使用synchronization同步的方式来确保在消息被发布给主题之前,通知只能被发送到注册的观察者处。此处是观察者的实现。他们将一直关注subject对象。package com.journaldev.design.observer;

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;

}

}

注意,update()方法的实现使用了被观察者的getUpdate()来处理更新的消息。此处应该避免把消息作为参数传递给update()方法。

下面是一个简单的测试程序来验证话题类的实现。package com.journaldev.design.observer;

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

观察者模式的UML图

786539e90ff913620d61b1f5d33c3b46.png

观察者模式也被叫做发布订阅模式。JAVA中的一些具体应用如下:Swing java.util.EventListener

javax.servlet.http.HttpSessionBindingListener

javax.servlet.http.HttpSessionAttributeListener

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值