观察者模式
观察者模式也可以被称为注册/订阅模式.当一个对象的状态发生变化的时候,所有依赖于它的其他类会受到通知并自动更新.
UML图示
观察者模式所含有的角色
- 主题(Subject):接口,一定会拥有添加观察者方法的定义以及通知观察者的方法定义。
- 具体主题(SubjectImpl):类,实现主题的一个实例。
- 观察者(Observer):接口,拥有接受主题发送消息的方法定义。
- 具体观察者(ObserverImpl):类,拥有主题对象的引用、接受消息的实现以及调用主题对象添加观察者方法的程序段。
举例
接口(MessageReceiver.java)用于接受外部传来的各种消息,存在MessageHandler.java接口用于处理消息。同时TradeReceiver.java用于接收trade消息,同时需要在接到消息后通知StringMessageHandler.java以及MapMessageHandler.java用于处理不同类型的trade消息。
类结构
- MessageHandler
package Handler;
public interface MessageHandler {
public void handleMessage();
}
-MapObjectMessagerHandler.java
MessageHandler的实现类,拥有处理消息的具体实现以及将本类的实例加入subject的名单中(注册)。
package Handler.Impl;
import Handler.MessageHandler;
import Recevier.MessageReceiver;
/**
* Created by YL28537 on 10/09/2018.
*/
public class MapObjectMessageHandler implements MessageHandler {
private MessageReceiver messageReceiver;
public MapObjectMessageHandler(MessageReceiver messageReceiver){
this.messageReceiver = messageReceiver;
messageReceiver.addHandler(this);
}
@Override
public void handleMessage(){
System.out.println("Handling by MapObjectMessageHandler");
}
}
- StringMessageHandler.java
package Handler.Impl;
import Handler.MessageHandler;
import Recevier.MessageReceiver;
/**
* Created by YL28537 on 10/09/2018.
*/
public class StringMessageHandler implements MessageHandler{
private MessageReceiver messageReceiver;
public StringMessageHandler(MessageReceiver messageReceiver){
this.messageReceiver = messageReceiver;
messageReceiver.addHandler(this);
}
@Override
public void handleMessage(){
System.out.println("Handling by StringMessageHandler");
}
}
- Recevier.java
package Recevier;
import Handler.MessageHandler;
/**
* Created by YL28537 on 10/09/2018.
*/
public interface MessageReceiver {
public void addHandler(MessageHandler messageHandler);
public void deleteHandler();
public void notifyAllHandler();
}
- TradeRecevier.java
package Recevier.Impl;
import Handler.MessageHandler;
import Recevier.MessageReceiver;
import java.util.ArrayList;
/**
* Created by YL28537 on 10/09/2018.
*/
public class TradeReceiver implements MessageReceiver {
private ArrayList<MessageHandler> handlers= new ArrayList<>();
@Override
public void addHandler(MessageHandler messageHandler) {
handlers.add(messageHandler);
}
@Override
public void deleteHandler() {
if(handlers.size()!=0){
for(int i = 0 ; i <= handlers.size() ; i++){
handlers.remove(1);
}
}else{
return;
}
}
@Override
public void notifyAllHandler() {
if(handlers.size()!=0){
for(MessageHandler handler : handlers){
handler.handleMessage();
}
}else{
System.out.println("No avaliable Handlers!");
return;
}
}
}
- Application.java
import Handler.Impl.MapObjectMessageHandler;
import Handler.Impl.StringMessageHandler;
import Recevier.Impl.TradeReceiver;
import Recevier.MessageReceiver;
/**
* Created by YL28537 on 10/09/2018.
*/
public class Application {
public static void main(String[] args){
MessageReceiver receiver = new TradeReceiver();
//setup a MapObjectMessageHandler
MapObjectMessageHandler mapObjectMessageHandler= new MapObjectMessageHandler(receiver);
//setup a StringMessageHandler
StringMessageHandler stringMessageHandler = new StringMessageHandler(receiver);
//handle Message
receiver.notifyAllHandler();
}
}
模拟使用Spring来管理
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<bean id="subject" class="Recevier.MessageReceiver" />
<bean id="subjectImpl" parent="subject" class="Recevier.Impl.TradeReceiver"/>
<bean id="observer" class="Handler.MessageHandler"/>
<bean id="objectImpl1" parent="observer" class="Handler.Impl.StringMessageHandler">
<property name="messageReceiver" ref="subject"/>
<constructor-arg>
<ref-bean="subject"/>
</constructor-arg>
</bean>
</beans>
推数据与拉数据
推数据:直接告诉observer实际的消息内容。
拉数据:将变化后的消息存到某个对象中,然后告诉observer变化的消息,observer根据自身需求决定取回的消息内容。
观察者模式与多主题
一个观察者可以订阅多个主题,要求某一主题发生变化后,通知本类。
实现:只需要在observer中添加逻辑,决定接受哪一主题。