簡體   English   中英

這是觀察者模式還是其他?

[英]Is this the Observer pattern or something else?

這是我一直在努力的一些代碼,這些代碼受Singleton和Observer的啟發,但實際上兩者都不是。 這是其他模式還是僅僅是雜種? 上下文是一個Android應用,其中多個Activity對象可能會對與特定帳戶相關聯的對象感興趣。 當第一個Activity注冊自己時,它將加載數據,並在沒有更多觀察者時釋放數據。

我想知道,例如,使用類變量和方法來管理這些對象和觀察者是否是一個可怕的主意。 歡迎任何反饋。

這個問題最初是關於何時通知觀察者是否正在注冊的對象的問題。 當我鍵入問題時,我意識到在純Observer中,Observable 一件有趣的事情,並且不涉及靜態方法。

public class MyObserver{
    public MyObserver(String id){
        MyObservable.addObserver(this, id);
    }

    public void update(MyObservable myObservable){
        ... do something with myObservable ...
            ... maybe based on myObservable.id ...
    }
}

public class MyObservable{

    /*********************************
     * Object management static code *
     *********************************/
    private static Map<String,Set<MyObserver>> observers;
    static{
        observers = new Map<String,Set<MyObserver>>();
    }

    private static Map<String,MyObservable> instances;
    static{
        instances = new HashMap<String,MyObservable>();
    }

    private static void addObserver(MyObserver myObserver, String id){
        Set<MyObserver> myObservers = observers.get(id);
        if(myObservers==null){
            myObservers = new Set<MyObserver>();
            observers.put(myObservers);
        }
        myObservers.add(id);

        MyObservable instance = instances.get(id);
        if(instance!=null){
            myObserver.update(instance);
        } else {
            loadData(id);
        }
    }

    private static void removeObserver(MyObserver myObserver, String id){
        Set<MyObserver> myObservers = observers.get(id);
        if(myObservers!=null){
            myObservers.remove(myObserver);
            if(myObservers.isEmpty()){
                instances.remove(id);
            }
        }
    }

    private static void loadData(String id){
        MyObservable  myObservable = ... asynchronous code to load myObservable ...
        ... callback will call MyObservable.set(id,  myObservable); ...
    }

    private static void set(MyObservable myObservable){
        String id=myObservable.getId();
        instances.put(id, myObservable);
        Set<MyObserver> myObservers = observers.get(id);
        if(myObservers!=null){      
            for(MyObserver myObserver:myObservers){
                myObserver.update(myObservable);
            }       
        }
    }

    /**********************************************
     * Data Object instance variables and methods *
     **********************************************/
    public MyObservable(String id){
        myId=id;
    }

    private string myId;
    private String myData1;
    private String myData2;
    private String myData3;
    ... getters and setters ...

}

關於觀察者模式的任何事情都沒有說明它必須如何實現,僅表示在誰在觀看和在誰被觀看之間存在關系。 沒有什么說不能在實現中使用多種模式。

這種實現方式的一個問題是,除非對對象的生命周期進行非常仔細的管理,否則您將獲得許多對對象的引用,而這些對象不再有人關心。

在Java中,習慣用法是使用“偵聽器”。 您應該有一個名為XListener的接口。 它將定義類似您的更新方法的內容。 然后,您只需使用方法addXListener(Xlistener)removeXListener(XListener)觀察。 它們維護一個可以通知的偵聽器列表(未設置)。 可觀察對象可以具有相同的偵聽器不止一次。 沒有什么是靜態的。 查看java.beans.PropertyChangeSupportjava.beans.PropertyChangeListener

您所擁有的兩個主要問題是:

  1. 可觀察的靜態內容。 為什么是靜態的? 如果只需要該類的一個可觀察對象,則可以使用Singleton模式。 但是您應該改用依賴注入。
  2. 可觀察者與觀察者之間的強耦合。 XListener接口不應該知道您將擁有的可觀察對象。 否則,您將引入循環依賴關系,並且您將不再針對接口而不是實現進行編程。

它是一個SingletonObserver

全局事件處理程序可以這種方式工作,例如,為swing中的任何關鍵事件注冊偵聽器。

確保小心添加和刪除觀察者,以避免內存泄漏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM