Java設計模式 - 觀察者模式
阿新 • • 發佈:2018-11-24
觀察者模式
觀察者模式也可以被稱為註冊/訂閱模式.當一個物件的狀態發生變化的時候,所有依賴於它的其他類會受到通知並自動更新.
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中新增邏輯,決定接受哪一主題。