Просмотр переменной на предмет изменений без опроса

Метод on может заменить как bind, так и delegate в зависимости от того, как он используется (а также click, поскольку bind может заменить это):

.click(handler) == .on('click', handler)

.bind('click', handler) ==  .on('click', handler)

.delegate('click', '#id', handler) == .on('click', '#id', handler)

Ни click, delegate или bind до сих пор перешли на устаревшую страницу . Я сомневаюсь, что метод click когда-либо будет.

11
задан squarism 12 May 2010 в 21:32
поделиться

4 ответа

Да, обработка событий - ключ к решению вашей проблемы. Во фрагменте кода C #, который вы показываете, также используется обработка событий, чтобы сообщить слушателям об изменении свойства. В Java также есть PropertyChangeEvent, который используется для большинства компонентов. (Например: компоненты Swing используют их).

Однако вы можете сделать это вручную: (хотя это уже не POJO, а скорее Java Bean)

EventBean.java :

import java.util.LinkedList;
import java.util.List;

public class EventBean {

    private final List<Listener> listeners = new LinkedList<Listener>();

    protected final <T> void firePropertyChanged(final String property,
            final T oldValue, final T newValue) {
        assert(property != null);
        if((oldValue != null && oldValue.equals(newValue))
                || (oldValue == null && newValue == null))
            return;
        for(final Listener listener : this.listeners) {
            try {
                if(listener.getProperties().contains(property))
                    listener.propertyChanged(property, oldValue, newValue);
            } catch(Exception ex) {
                // log these, to help debugging
                ex.printStackTrace();
            }
        }
    }

    public final boolean addListener(final Listener x) {
        if(x == null) return false;
        return this.listeners.add(x);
    }
    public final boolean removeListener(final Listener x) {
        return this.listeners.remove(x);
    }

}

Listener.java :

import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;

// Must be in same package as EventBean!
public abstract class Listener {

    private final Set<String> properties;

    public Listener(String... properties) {
        Collections.addAll(this.properties = new TreeSet<String>(), properties);
    }

    protected final Set<String> getProperties() {
        return this.properties;
    }

    public abstract <T> void propertyChanged(final String property,
            final T oldValue, final T newValue);
}

И реализуйте свой класс следующим образом:

public class MyBean extends EventBean {

    private boolean typedA;

    public void setTypedA(final boolean newValue) {
        // you can do validation on the newValue here
        final boolean oldValue = typedA;
        super.firePropertyChanged("typedA", oldValue, newValue);
        this.typedA = newValue;
    }
    public boolean getTypedA() { return this.typedA; }

}

Который вы можете использовать как:

MyBean x = new MyBean();
x.addListener(new Listener("typedA") {
    public <T> void propertyChanged(final String p,
                 final T oldValue, final T newValue) {
        System.out.println(p + " changed: " + oldValue + " to " + newValue);
        // TODO
    }
});

x.setTypedA(true);
x.setTypedA(false);
x.setTypedA(true);
x.setTypedA(true);
7
ответ дан 3 December 2019 в 08:03
поделиться

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

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

Вы также можете посмотреть пример википедии для шаблона наблюдателя .

7
ответ дан 3 December 2019 в 08:03
поделиться

Фактически, дополнительный поток не нужен. Вы должны позволить ObserverStillPolling расширить Observable и уведомить наблюдателей, когда input.equals ("a") .

Да, это означает, что сам объект POJO должен расширять Observable и уведомлять самих наблюдателей.


Тем не менее, Observer / Observable на самом деле плохо спроектированы. Я бы посоветовал создать свой собственный интерфейс PropertyChangeListener и позволить вашему POJO реализовать его. Затем позвольте POJO зарегистрировать себя в наблюдателе во время построения или сделать это динамически, проверив где-нибудь instanceof PropertyChangeListener , если применимо.

1
ответ дан 3 December 2019 в 08:03
поделиться

Возможно, решение - wait () / notify () или одна из утилит параллелизма Java. Эти конструкции избегают опроса «занято-ожидание», о котором, кажется, идет речь.

Они используются с несколькими потоками. Один поток доставляет событие, другие на него отвечают. Вот пример:

class SyncQueue {

  private final Object lock = new Object();

  private Object o;

  /* One thread sends "event" ... */
  void send(Object o)
    throws InterruptedException
  {
    if (o == null)
      throw new IllegalArgumentException();
    synchronized (lock) {
      while (this.o != null)
        lock.wait();
      this.o = o;
      lock.notifyAll();
    }
  }

  /* Another blocks (without burning CPU) until event is received. */
  Object recv()
    throws InterruptedException
  {
    Object o;
    synchronized (lock) {
      while (this.o == null)
        lock.wait();
      o = this.o;
      this.o = null;
      lock.notifyAll();
    }
    return o;
  }

}
0
ответ дан 3 December 2019 в 08:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: