Это шаблон наблюдателя или что-то еще? - PullRequest
0 голосов
/ 27 октября 2011

Это код, над которым я работал, который вдохновлен Синглтоном и Обозревателем, но на самом деле ни то, ни другое. Это какой-то другой паттерн или просто дурак? Контекст для этого - приложение для Android, где несколько объектов Activity могут быть заинтересованы в объекте, связанном с определенной учетной записью. Он загружает данные, когда регистрируется первая активность, и позволяет отправлять данные, когда больше нет наблюдателей.

Я хотел бы знать, например, ужасно ли использовать переменные и методы класса для управления этими объектами и наблюдателями. Любая обратная связь приветствуется.

Этот вопрос начинался как вопрос о том, когда следует уведомлять Наблюдателя, если объект, для которого он регистрируется, уже существует. Когда я набирал вопрос, я понял, что в чистом Observer наблюдаемая равна , интересная вещь и статические методы не задействованы.

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 ...

}

Ответы [ 3 ]

2 голосов
/ 27 октября 2011

Ничто в шаблоне наблюдателя не говорит о том, как оно должно быть реализовано, это просто означает, что есть связь между тем, кто смотрит, и тем, кто за ним наблюдает. Ничто не говорит о том, что в реализации нельзя использовать несколько шаблонов.

Одна проблема с этим типом реализации состоит в том, что, если жизненный цикл объекта не является очень тщательно управляемым, вы получите множество ссылок на объекты, которые больше никому не нужны.

1 голос
/ 27 октября 2011

В Java идиома заключается в использовании «Listeners».У вас должен быть интерфейс с именем XListener.Это определит что-то вроде вашего метода обновления.Тогда у вас просто есть свои наблюдаемые с методами addXListener(Xlistener) и removeXListener(XListener).Они поддерживают список (не установлен) слушателей, о которых можно уведомить.Наблюдаемый объект может иметь одного и того же слушателя более одного раза.Ничто не статично.Проверьте java.beans.PropertyChangeSupport и java.beans.PropertyChangeListener.

Две основные проблемы с тем, что у вас есть:

  1. Статические вещи в наблюдаемом.Почему статический?Если вам нужен только один наблюдаемый объект этого класса, то вы можете использовать шаблон Singleton.Но вместо этого вы должны использовать внедрение зависимостей.
  2. Сильная связь между наблюдаемым и наблюдателем.Интерфейс XListener не должен знать о наблюдаемых, которые у вас будут.В противном случае вы вводите циклическую зависимость и больше не программируете интерфейс вместо реализации.
0 голосов
/ 27 октября 2011

Это Singleton и Observer.

Глобальные обработчики событий могут работать таким образом, например, регистрация слушателей для любого ключевого события в колебании.

Убедитесь, что вы добавили и удалилиВнимательно следите за тем, чтобы не допустить утечки памяти.

...