2

Observerパターンに関連する次の問題の設計パターン/解決策を探しています。すでに調査しました。

私のコードにはMyModelクラスがあります。多くのプロパティがあります。

public class MyModel {

    private List<Flower> flowers = new ArrayList<Flower>();
    private List<Toys> toys = new ArrayList<Toys>();
    private List<Coffee> coffees = new ArrayList<Coffee>();

    private List<IBusinessEntityListener> listener =
            new ArrayList<IBusinessEntityListener>();

    public void addChangeListener(IBusinessEntityListener newListener) {
        listener.add(newListener);
    }

}

したがって、実装するクラスはクラスにIBusinessEntityListener登録できますMyModel

次に、の一部のプロパティのみに関心のある10以上のリスナーがいますMyModel。それらはすべて実装しIBusinessEntityListenerます。Flowersしかし、一部のリスナーが のみに関心がある、一部のリスナーが のみに関心があるToys、などを指定するにはどうすればよいでしょうか (たとえば、Java Generics を使用して?) 。

では、特定のプロパティのリッスンをサポートするようなクラス構造を設計するにはどうすればよいでしょうか?

とにかく、すべてのリスナーは、操作addupdate、およびdeleteの 3 つのメソッドを実装します。

4

2 に答える 2

2

Extrinsic Visitorパターンの適用はどうですか?

プロパティのインターフェイスを定義します。

public interface ListenableProperty {
    // Degenerate interface for listeners
    public interface Listener {}

    public void acceptUpdate(Listener listener);
}

次に、各プロパティのクラスと各プロパティのListenerインターフェイスを実装し、モデルから次のように使用します。

public class MyModel {
    public static class FlowersProperty implements ListenableProperty {
        public interface Listener extends ListenableProperty.Listener {
            public void update(FlowersProperty p);
        }

        @Override
        public void acceptUpdate(ListenableProperty.Listener listener) {
            if (listener instanceof FlowersProperty.Listener) {
                Listener myListenerType = (Listener)listener;
                myListenerType.update(this);
            }
        }

        // some property accessors here
    }

    public static class ToysProperty implements ListenableProperty {
        public interface Listener extends ListenableProperty.Listener {
            public void update(ToysProperty p);
        }

        @Override
        public void acceptUpdate(ListenableProperty.Listener listener) {
            if (listener instanceof ToysProperty.Listener) {
                Listener myListenerType = (Listener)listener;
                myListenerType.update(this);
            }
        }

        // some property accessors here
    }

    private FlowersProperty flowers = new FlowersProperty();
    private ToysProperty toys = new ToysProperty();
    private List<ListenableProperty> properties = new ArrayList();

    // CopyOnWrite so that listeners can remove themselves during update if desired
    private List<ListenableProperty.Listener> listeners = 
            new CopyOnWriteArrayList<>();

    // Convenience interface for implementors that want all properties
    public interface AllPropertiesListener extends
        FlowersProperty.Listener,
        ToysProperty.Listener 
    {}

    public MyModel() {
        properties.add(flowers);
        properties.add(toys);
    }

    public void addListener(ListenableProperty.Listener l) {
        if (!listeners.contains(l)) {
            listeners.add(l);
        }
    }

    private void updateAll() {
        for (ListenableProperty p : properties) {
            for (ListenableProperty.Listener l : listeners) {
                p.acceptUpdate(l);
            }
        }
    }

    private void updateToys() {
        for (ListenableProperty.Listener l : listeners) {
            toys.acceptUpdate(l);
        }
    }

    private void updateFlowers() {
        for (ListenableProperty.Listener l : listeners) {
            flowers.acceptUpdate(l);
        }
    }
}

リスナーは、好きなだけ多くまたは少数のリスナー インターフェイスを実装するか、便利なインターフェイスを介してすべてを実装できます。MyModel.AllPropertiesListener

個々のプロパティの更新ルーチンをプロパティ自体に移動することもできます。

于 2014-03-15T11:50:35.820 に答える
1

どのタイプのリスナーにもクラスがあります:

FlowerListerner implemts IBusinessEntityListener;
ToyListerner implemts IBusinessEntityListener;

およびリスナーリスト:

public class MyModel {

    private List<Flower> flowers = new ArrayList<Flower>();
    private List<Toys> toys = new ArrayList<Toys>();

    private List<IBusinessEntityListener> flowerListeners =
            new ArrayList<IBusinessEntityListener>();

    private List<IBusinessEntityListener> toyListeners =
            new ArrayList<IBusinessEntityListener>();

    public void addListener(IBusinessEntityListener newListener) {
        if(newListener instance of FlowerListener)
            flowerListeners.add(newListener);
        else if (newListener instance of ToyListener)
    }       toyListeners.add(newListener);

    updateFlowerListeners() { ....}
    updateToyListeners() { ....}

}

また、各プロパティへの変更は、関連するリスナーに反映されます。

アップデート

別の解決策は、リスナーオブジェクトに関心のあるリストを持っていることです:

Class Listener {

  private List<Class> interests;

  public Listener(List<Class> interests) {
    this.interests = interests;
  }

  public boolean isInterested(Class clazz) {
    return list.contains(clazz);
  }

  public void update() { ... }
}

モデル内:

public class MyModel {

    private List<Flower> flowers = new ArrayList<Flower>();
    private List<Toys> toys = new ArrayList<Toys>();

    private List<Listener> listeners =
            new ArrayList<Listener>();

    public void addListener(Listener newListener) {
        listeners.add(newListener);
    }     

    updateFlowerListeners() {
        for(Listener l : listerners) {
           if(l.isInterested(Flower.class)
               l.update();       
    }

    updateToyListeners() { ...  }

}
于 2014-03-15T10:27:46.433 に答える