5

私はこの主題が死に至るまでカバーされていることを認識していますが、私はまだ苦労しており、特定の助けが必要です.

私の目的は、ある種のオブザーバブル (Dog としましょう) とある種のリスナー (Owner としましょう) の間に単純な Observer パターンを実装することです。

最終的に、MVC パラダイムでは、Owner は「ビュー」になり、Dog は「モデル」になります。ここで物事を単純化しようとするためだけに、Dog と Owner を使用しています。

Java のビルトイン Observer/Observable クラスを使用しようとしましたが、Observers の update() メソッドがいかに悪いかを認識しました。POJO を受け取り、その POJO を update() メソッドでチェック/キャストする必要があります。「update()」メソッドが期待できるものを受け取るようにしたいと思っています。

そのため、犬/所有者を例として使用するこのチュートリアルを含む、いくつかのチュートリアルに従いました。

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

そのため、1 つの update() メソッドではなく、特定のイベントを処理するメソッドを用意しました。素晴らしい。私は現在、オーナー/ビュー クラスに満足しています。それは犬/モデルの方法を知っていて、それは問題ありません(私は思います)。

私が気に入らないのは、犬/モデルが所有者/ビューのメソッドへの参照を持っていることです。私は数え切れないほど読んできましたが、モデルが上記のようにビューに密接に結合されるべきではないことに完全に同意します。また、ほぼ同じことを行う犬/モデルのすべての「火」メソッドにも熱心ではありません。すべてのリスナーをループし、各リスナーで異なるメソッドを呼び出すだけです。

この関係をさらに切り離して、犬/モデルが特定のメソッドを呼び出さないようにすることは可能ですか? もしそうなら、犬/モデルデータを所有者/ビューに受け取り、それを適切に操作するための最良の方法は何ですか?

ありがとう

4

2 に答える 2

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

この場合、はの実装を認識してDogいません。OwnerOwnerDogListener

一方Owner、 は については知りません。Dog着信があることを知っているだけDogEventです。

于 2013-05-11T15:07:32.620 に答える
1

MVC の目的 (特に MVP の場合) のために、私はイベント ベース プログラミングで良い経験を積んできました。そのため、Dog と Owner が使用する EventBus が必要になります。オーナーは HungerLevelIncrease などの特定のイベント クラスをサブスクライブし、犬はそのようなイベントを発生させます。あなたの犬の所有者の例では、所有者は自分の犬を知らなかったので、これはちょっと奇妙ですが、GUI プログラミングの場合、これは特に他のコントローラー間で物事を分離するための便利で簡単なソリューションです。

自分で Bus を簡単に作成することも、Google guavaのものを使用することもできます。

これは、本当に疎結合を作成するために私が知っている最善の方法です。

于 2013-05-11T15:05:06.843 に答える