松散耦合的观察者模式

who*_*tdk 5 java model-view-controller loose-coupling observer-pattern

我意识到这个问题已经被解决了,但我仍在努力,可以做一些具体的帮助.

我的目标是在某种可观察的(可以说是狗)和某种倾听者(比如所有者)之间实现一个简单的观察者模式.

最终,所有者将成为MVC范例中的"视图"和"狗"模型.我正在使用Dog和Owner来尝试简化这里的事情.

我试图使用Java内置的Observer/Observable类,但已经意识到Observers update()方法有多糟糕 - 它接收到POJO,我需要在update()方法中检查/转换该POJO.我更愿意让我的'update()'方法收到它可以期待的东西.

所以,我遵循了一些教程,包括使用Dog/Owner作为示例的教程:

http://www.youtube.com/watch?v=qw0zZAte66A

在这里,我已经展示了如何滚动我自己的Observer/Observed类.在伪代码中,我现在拥有的是:

Dog/Model {

    List listeners;

    public fireDogHungryEvent() {

        foreach listener {
            listener.onDogHungry(this);
        }
    }

    public fireDogPeeEvent() {

        foreach listener {
            listener.onDogNeedsToPee(this);
        }
    }

    public getHungerLevel() { return hungerLevel; }
    public getBladderCapacity() { return bladderCapacity; }
}

Owner/View {

    public onDogHungry(model) {
        println(model.getHungerLevel());
    }

    public onDogNeedsToPee(model) {
        println(model.getBladderCapacity());
    }
}
Run Code Online (Sandbox Code Playgroud)

所以现在而不是一个update()方法,我有处理特定事件的方法.辉煌.我目前对所有者/视图类感到满意.它知道Dog/model的方法,这很好(我认为).

我不喜欢的是Dog/model引用了Owner/view中的方法.我已经阅读过无数次并且完全同意模型不应该与其视图紧密耦合,例如它似乎在上面.我也不热衷于狗/模型中的所有'火'方法几乎做同样的事情; 循环遍及其所有侦听器,并在每个侦听器上调用不同的方法.

是否有可能进一步解除这种关系,而不是具有Dog/model调用特定方法?如果是这样,将狗/模型数据接收到所有者/视图并适当地使用它的最佳方法是什么?

谢谢

Bor*_*der 4

您应该从和 中interface获取具体实现的知识ObserverObservable

public enum EventType {

    HUNGRY,
    PEE;
}

public interface DogEvent {

    EventType getType();
}

public interface DogListener {

    void fireEvent(DogEvent event);
}

public class Dog {

    private final Set<DogListener> listeners = new CopyOnWriteArraySet<DogListener>();

    public void register(final DogListener dogListener) {
        listeners.add(dogListener);
    }

    public void unregister(final DogListener dogListener) {
        listeners.remove(dogListener);
    }

    public void firePeeEvent() {
        fireEvent(new DogEvent() {
            @Override
            public EventType getType() {
                return EventType.PEE;
            }
        });
    }

    public void fireHungryEvent() {
        fireEvent(new DogEvent() {
            @Override
            public EventType getType() {
                return EventType.HUNGRY;
            }
        });
    }

    private void fireEvent(final DogEvent dogEvent) {
        for (final DogListener listener : listeners) {
            listener.fireEvent(dogEvent);
        }
    }
}

public class Owner implements DogListener {

    @Override
    public void fireEvent(DogEvent event) {
        switch (event.getType()) {
            case PEE:
                System.out.println("Someone take the dog out");
                break;
            case HUNGRY:
                System.out.println("I can't believe the dog is hungry _again_!");
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Dog不知道 的实现,Owner它只知道 是Owner一个DogListener

另一方面,Owner不知道它只Dog知道它有一个传入DogEvent