亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 觀察者模式或發布者-訂閱者模式的變體

Java 觀察者模式或發布者-訂閱者模式的變體

慕標5832272 2023-02-23 09:54:44
以下 2 個變體的實際觀察者模式是什么。在第一個中,Observer 負責訂閱。但在第二種情況下,發布者負責將特定觀察者添加到訂閱者列表中。因為,網絡中有一些實現,將它們都作為 java 中的觀察者模式。    // 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);      }
查看完整描述

4 回答

?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

第二個例子是實現所謂的觀察者模式。(觀察者)想要得到關于被觀察對象 X(Observable/事件源)中發生的某些事件的通知,對吧?然后你會告訴Observable 通知你?;蛘邠Q句話說,你開始監聽觀察者的通知——這就是為什么觀察者也被稱為監聽者。

Observable 并不知道它所有的訂閱者。它只通過 egIObserver接口了解監聽器,接口定義了實際的通知回調。Observable 只是將觀察者添加到容器或集合中。


第一個例子沒有意義。observable 調用觀察者的方法讓他訂閱?那個設計流程一定很奇怪。


假設您有一個FileWriter暴露事件的類FileWriter.Completed。您有另一個FileHandler管理所有文件的類。來電。FileHandler_FileWriter.write(filePath, data)


每次寫入操作后,FileHandler必須向用戶顯示一條消息。因此FileWriter被 所使用FileHandler,但不知道誰在調用該write方法。作為FileHandler的眾多消費者之一FileWriter.write(string, string),知道FileWriter implements an observable interface called IWriteToFileCompletedEvent and defines the methodFileWriter.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.

}

完全不同類型(SettingsHandler和ContactsHandler)但通用基礎/接口類型的多個對象訂閱了事件源的同一事件。一切都很干凈。使用事件源對象的對象實際上訂閱/監聽??捎^察的類,observable,只是通知所有的監聽者。沒有其他互動。


總結一下:您的解決方案 1 一點也不方便(盡管您可以讓它工作)并且會產生丑陋的代碼。


解決方案 2實際上遵循描述如何實現事件的模式。此實現已被證明并得到很好的確立,因為它實現了引入事件的目標并生成干凈且可讀的代碼。


查看完整回答
反對 回復 2023-02-23
?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

觀察者是應該注冊自己還是讓另一個實體來處理這個責任是應用觀察者模式時的一個實現決定,而不是模式本身的結構方面。因此,遇到這兩種變體也就不足為奇了。

在 GoF 書籍和其他地方記錄的模式結構中,Subject有一個Attach(和Detach)方法作為其接口的一部分。這意味著任何引用主題的實體都可以調用Attach并執行此注冊。


查看完整回答
反對 回復 2023-02-23
?
收到一只叮咚

TA貢獻1821條經驗 獲得超5個贊

我懷疑他們倆都是。他們都必須實現 Observer 接口。



查看完整回答
反對 回復 2023-02-23
?
呼喚遠方

TA貢獻1856條經驗 獲得超11個贊

兩者都是觀察者模式的有效實現,但是除非您明確需要公開觀察者列表,否則第二種方法更可取。



查看完整回答
反對 回復 2023-02-23
  • 4 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號