gpt4 book ai didi

java - Java 观察者模式或发布者-订阅者模式的变体

转载 作者:行者123 更新时间:2023-11-30 07:40:56 25 4
gpt4 key购买 nike

以下 2 个变体的实际观察者模式是什么。

  1. 在第一个中,Observer 负责订阅。
  2. 但在第二种情况下,Publisher 将将特定观察者添加到订阅者列表的责任。

因为,web 中有一些实现,将它们都作为 java 中的观察者模式。

    1.
    // Observer is taking the responsibility of subscribing 
// Observer.java
@Override
public void subscribe(MessagePublisher publisher) {
publisher.getObservers().add(this);
}

2.

    // Publisher is taking the observer to subscribe
// Publisher.java
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}

最佳答案

第二个例子是实现所谓的观察者模式。 (观察者)想要得到关于被观察对象 X(Observable/事件源)中发生的某些事件的通知,对吗?然后你会告诉 Observable 通知你。或者换句话说,你开始监听观察者的通知——这就是为什么观察者也被称为监听者。
Observable 并不知道它所有的订阅者。它只通过它们的例如 IObserver 接口(interface)了解监听器,该接口(interface)定义了实际的通知回调。 Observable 只是将观察者添加到容器或集合中。

第一个例子没有意义。 observable 调用观察者的方法让他订阅?这个设计流程一定很奇怪。

假设您有一个 FileWriter 类,它公开了一个事件 FileWriter.Completed。您有另一个管理所有文件的类 FileHandlerFileHandler 调用 FileWriter.write(filePath, data)

在每次写入操作后,FileHandler 必须向用户显示一条消息。所以 FileWriterFileHandler 使用,但不知道是谁在调用 write 方法。 FileHandlerFileWriter.write(string, string) 的众多消费者之一,它知道 FileWriter 实现了一个名为 IWriteToFileCompletedEvent并定义方法FileWriter.subscribeToWriteToFileCompleted(IObserver eventListener)`。

这就是“现实生活”中真正的实现方式

// The interface for the publisher or observable of a special event
interface IWriteToFileCompletedEvent {
void subscribeToWriteToFileCompleted(IWriteToFileCompletedListener observer);
void unsubscribeToWriteToFileCompleted(IWriteToFileCompletedListener observer);
}

// The interface for the observer of a special event
interface IWriteToFileCompletedListener {
void notify(string filePathOfCompletedFile);
}

// The observable that exposes a special event
class FileWriter implements IWriteToFileCompletedEvent {
private List<IWriteToFileCompletedListener> writeToFileCompletedListeners = new ArrayList<>();

public void subscribeToWriteToFileCompleted(IWriteToFileCompletedListener observer) {
this.writeToFileCompletedListeners.add(observer);
}

public void unsubscribeToWriteToFileCompleted(IWriteToFileCompletedListener observer) {
this.writeToFileCompletedListeners.remove(observer);
}

public void writeToFile(string filePath, string data) {
// Write data to file
// Once done notify all listeners of the write completed event
for (IWriteToFileCompletedListener observer : this.writeToFileCompletedListeners) {
observer.notify(filePath);
}
}
}

// The observer of a special event
class ContactsHandler implements IWriteToFileCompletedListener {
private FileWriter fileWriter = new FileWriter();

public void saveUserContactToFile(string filePath, string userInput) {
this.fileWriter.subscribeToWriteToFileCompleted(this);
this.fileWriter.writeToFile(filePath, userInput);
}

// Implementation of interface IWriteToFileCompletedListener
public void notify(string filePath) {
this.fileWriter.unsubscribeToWriteToFileCompleted(this);
this.messageDialog.show("The new contact was successfully saved to " + filePath);
}
}

// Another observer of a special event
class SettingsHandler implements IWriteToFileCompletedListener {
private FileWriter fileWriter = new FileWriter();

public void saveUserSettingsToFile(string filePath, string userSettings) {
this.fileWriter.subscribeToWriteToFileCompleted(this);
this.fileWriter.writeToFile(filePath, userSettings);
}

// Implementation of interface IWriteToFileCompletedListener
public void notify(string filePath) {
this.fileWriter.unsubscribeToWriteToFileCompleted(this);
this.messageDialog.show("The new settings were successfully saved to " + filePath);
}
}

类将像这样交互

public void main(strng[] args {
SettingsHandler settingsHandler = new SettingsHandler();
ContactsHandler contactsHandler = new ContactsHandler();

// Imaging this method receives user input fromo the UI:
string newContact = textBox.gettext();
this.contactsHandler.saveUserContactToFile("C:\Contacts.txt", newContact);

// While waiting for the message to show the user adjusted some settings and clicked 'save'
string changedSettings = getChangedSettings();
this.settingsHandler.saveUserSettingsToFile("C:\UserSettings.txt", changedSettings);

// After a while the user sees the messages send from the event listeners.
}

完全不同类型(SettingsHandlerContactsHandler)但通用基础/接口(interface)类型的多个对象订阅了事件源的相同事件。一切都很干净。使用事件源对象的对象实际上订阅/监听。可观察的类,observable,只是通知所有的监听者。没有其他互动。

总结一下:您的解决方案 1 一点也不方便(尽管您可以让它工作)并且会产生难看的代码。

解决方案 2 实际上遵循描述如何实现事件的模式。此实现已被证明并得到很好的确立,因为它实现了引入事件的目标并生成了清晰易读的代码。

关于java - Java 观察者模式或发布者-订阅者模式的变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56799804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com