2017-01-05 2 views
1

Предположим, у меня есть вещатель класса для трансляции определенных событий. Например:Шаблон наблюдателя с фильтром, на каком уровне фильтровать?

List<Observers> observers = … 

Public void broadcast(Event e) { 
    for (each observer: observers) { 
     observer.observe(e); 
    } 
} 

Тогда у меня есть класс, называемый EventReceiver, который делает следующее

public void processEvent(Event e) { 
    saveToDatabase(e); 
    broadcast(e); 
} 

Сейчас: новое требование приходит, говоря, что, когда событие имеет тип «Foo», мы должны сохранить он в базу данных, но не транслирует его.

На каком слое следует фильтровать? В broadcast.java или в EventReceiver.java?

Например:

Public void broadcast(Event e) { 
If (event != foo) { 
    for (each observer: observers) { 
     observer.observe(e); 
    } 
} 
} 

Или

public void processEvent(Event e) { 
    saveToDatabase(e); 
    If (event != foo) { 
     broadcast(e); 
    } 
} 

ответ

2

Я бы сказал processEvent, ваш второй образец. Ответственность за фильтрацию должна исходить от тела кода, сначала обрабатывающего событие, прежде чем вы решите его транслировать. Нет смысла передавать событие на broadcast, которое не будет или не должно транслироваться.

0

Если у вас есть 2 наблюдателя, одна трансляция и другая запись в БД, то вы можете использовать шаблон Decorator для фильтрации.

class Broadcaster implements Observer { 
    public void process(Event e) { 
     broadcast(e); 
    } 
} 


class DbWriter implements Observer { 
    public void process(Event e) { 
     writeToDb(e); 
    } 
} 



class FilterOutFoo implements Observer { 
    private Observer decorated; 

    public Filter(Observer decorated) { 
     this.decorated = decorated; 
    } 

    public void process(Event e) { 
     if (!e.isFoo()) 
      decorated.processs(e); 
    } 
} 

observed.addObserver(new Broadcaster()); 
observed.addObserver(new FilterOutFoo(new DbWriter())); 
+0

Можете ли вы подробнее рассказать об этом? – JavaDeveloper

0

Фильтр должен быть четко реализован в EventReceiver.java, как вы могли бы обновить класс Broadcast.java позже транслировать другие события.

У вас может быть много приемников, каждый из которых реализует свой собственный фильтр в зависимости от варианта использования.

Кроме того, поскольку Michael указал, что нет никакого средства для вещания события, которое не будет транслироваться.

Это было бы похоже на заглушение башни сотового телефона вместо самого сотового телефона. Вы никогда не получите звонок. Но если вы отключите свой мобильный телефон, вы решаете, когда это нужно. (извините за coparison :))

0

Не фильтровать. Подкласс. Если есть событие типа Foo, тогда должен быть класс FooEvent. Пусть наблюдатели регистрируются для уведомлений FooEvent, чтобы наблюдатели получали уведомления, о которых они заботятся.

Корень проблемы - это один класс Event, представляющий несколько типов событий. Вместо этого каждый тип события должен иметь свой собственный класс и собственный список наблюдателей.