具有过滤器的观察者模式,在什么级别过滤?

时间:2017-01-05 19:19:09

标签: java design-patterns observer-pattern

假设我有一个班级广播员来播放某些事件。 例如:

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);
}

现在:出现了一个新的要求,说当Event类型为“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);
   }
}

4 个答案:

答案 0 :(得分:2)

我会说processEvent,你的第二个样本。在您决定广播之前,过滤的责任应该来自首先处理事件的代码体。将事件传递给broadcast没有或不应该被广播的事情是没有意义的。

答案 1 :(得分:0)

如果您有2个观察者,一个广播,另一个写入DB,那么您可以使用装饰器模式进行过滤。

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()));

答案 2 :(得分:0)

过滤器应该在EventReceiver.java中清楚地实现,因为您可以稍后升级Broadcast.java类以广播其他事件。

您可以拥有多个接收器,每个接收器根据用例实现自己的过滤器。

此外,正如Michael所指出的那样,广播一个不会被播放的事件毫无意义。

这就像静音手机信号塔而不是手机本身。你永远不会接到任何电话。但是,如果您将手机静音,则决定何时取消静音。 (对不起比较:))

答案 3 :(得分:0)

不要过滤。子类。如果存在类型为Foo的事件,那么应该有一个类 Accept: application/json 。让观察者注册FooEvent通知,以便观察者只接收他们关心的通知。

问题的根源是表示多种事件类型的单个FooEvent类。相反,每个事件类型都应该有自己的类和自己的观察者列表。