新聞動態(tài)
設(shè)計(jì)模式系列| 觀察者模式
常見問題 發(fā)布者:ou3377 2021-12-25 10:01 訪問量:315
這篇讓我們來認(rèn)識一下觀察者模式
觀察者模式
是一種行為設(shè)計(jì)模式, 允許你定義一種訂閱機(jī)制, 可在對象事件發(fā)生時(shí)通知多個(gè) “觀察” 該對象的其他對象。
1)當(dāng)一個(gè)對象狀態(tài)的改變需要改變其他對象, 或?qū)嶋H對象是事先未知的或動態(tài)變化時(shí), 可使用觀察者模式
。
2) 當(dāng)應(yīng)用中的一些對象必須觀察其他對象時(shí),可使用該模式。但僅能在有限時(shí)間內(nèi)或特定情況下使用。訂閱者可隨時(shí)加入或離開該列表。
有一個(gè)小區(qū),需要進(jìn)行核酸檢測。
假設(shè)每個(gè)人通過關(guān)注公眾號獲取核酸檢測結(jié)果。
/**
* 發(fā)布接口
*/
public interface IPublisher {
/**
* 發(fā)布事件
* @param event
*/
void publish(IEvent event);
}
/**
* 通用訂閱接口
*/
public interface ISubscriber {
/**
* 查看結(jié)果
*/
void look();
}
/**
* 通用事件接口
*/
public interface IEvent {
/**
* 打印事件信息
*/
void print();
}
/**
* 消息發(fā)送者
*/
public class Publisher implements IPublisher{
private IEvent event;
private List<ISubscriber> subscribers;
public Publisher(IEvent event, List<ISubscriber> subscribers) {
this.event = event;
this.subscribers = subscribers;
}
/**
* 發(fā)布消息
* @param event
*/
@Override
public void publish(IEvent event){
event.print();
}
public IEvent getEvent() {
return event;
}
public void setEvent(IEvent event) {
this.event = event;
}
public List<ISubscriber> getSubscribers() {
return subscribers;
}
public void setSubscribers(List<ISubscriber> subscribers) {
this.subscribers = subscribers;
}
}
/**
* 檢測事件
*/
public class CheckEvent implements IEvent{
private String name;
private String result;
private ISubscriber subscriber;
public ISubscriber getSubscriber() {
return subscriber;
}
public void setSubscriber(ISubscriber subscriber) {
this.subscriber = subscriber;
}
public CheckEvent(String name) {
this.name = name;
}
@Override
public void print() {
subscriber.look();
System.out.println("事件名稱:" + name);
System.out.println("事件結(jié)果:" + result);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
/**
* 訂閱者
*/
public class User implements ISubscriber{
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void look() {
System.out.println("檢測姓名:" + name);
}
}
/**
* 測試類
*/
public class TestDemo {
public static void main(String[] args) {
//定義兩種結(jié)果
String[] doc = {"陰性", "陽性"};
//初始化檢測事件
CheckEvent check = new CheckEvent("核酸檢測");
//初始化消息發(fā)布者
Publisher publisher = new Publisher(check,new ArrayList<>());
//實(shí)例化接受檢測的用戶
List<ISubscriber> users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
//初始化用戶
User user = new User("狼王" + i);
users.add(user);
}
//用戶訂閱事件
publisher.setSubscribers(users);
int index;
//發(fā)布檢測結(jié)果
for (int i = 0; i < 10; i++) {
System.out.println("---------------");
//隨機(jī)檢測結(jié)果
index = (int) (Math.random() * doc.length);
check.setSubscriber(users.get(i));
check.setResult(doc[index]);
//發(fā)布
publisher.publish(check);
}
}
}
---------------
檢測姓名:狼王0
事件名稱:核酸檢測
事件結(jié)果:陰性
---------------
檢測姓名:狼王1
事件名稱:核酸檢測
事件結(jié)果:陰性
---------------
檢測姓名:狼王2
事件名稱:核酸檢測
事件結(jié)果:陽性
---------------
檢測姓名:狼王3
事件名稱:核酸檢測
事件結(jié)果:陰性
---------------
檢測姓名:狼王4
事件名稱:核酸檢測
事件結(jié)果:陽性
---------------
檢測姓名:狼王5
事件名稱:核酸檢測
事件結(jié)果:陽性
---------------
檢測姓名:狼王6
事件名稱:核酸檢測
事件結(jié)果:陽性
---------------
檢測姓名:狼王7
事件名稱:核酸檢測
事件結(jié)果:陰性
---------------
檢測姓名:狼王8
事件名稱:核酸檢測
事件結(jié)果:陰性
---------------
檢測姓名:狼王9
事件名稱:核酸檢測
事件結(jié)果:陰性
分別定義了三個(gè)接口:事件接口,消息發(fā)布者接口,消息訂閱者接口
每個(gè)接口有其對應(yīng)的實(shí)現(xiàn)。
這樣設(shè)計(jì)利于后續(xù)的擴(kuò)展,在不同的事件和不同的訂閱者以及消息發(fā)布者,都可以進(jìn)行擴(kuò)展而不影響其他。
1)開閉原則
2)業(yè)務(wù)代碼解耦,具體消息訂閱者和發(fā)布者沒有直接關(guān)聯(lián)。
1)多個(gè)消費(fèi)者存在的時(shí)候,可能會無法控制順序和時(shí)間較長。
關(guān)鍵字: 觀察者模式 設(shè)計(jì)模式
文章連接: http://m.hsjyfc.com.cn/cjwt/860.html
版權(quán)聲明:文章由 晨展科技 整理收集,來源于互聯(lián)網(wǎng)或者用戶投稿,如有侵權(quán),請聯(lián)系我們,我們會立即刪除。如轉(zhuǎn)載請保留