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