2

我正在寻找与观察者模式相关的以下问题的设计模式/解决方案,我已经研究过。

在我的代码中,我有一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。但是我怎样才能指定(例如使用 Java 泛型?)一些听众只感兴趣Flowers,一些只感兴趣Toys,等等?

那么如何设计这种支持监听某些属性的类结构呢?

无论如何,所有侦听器都会为操作添加更新删除实现 3 种方法。

4

2 回答 2

2

外部访问者模式的应用怎么样?

为属性定义一个接口:

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

对于任何类型的Listeners都有一个类:

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() { ....}

}

并且对每个属性的任何更改都会反映给相关的侦听器。

更新

另一个解决方案是你有一个Listener Object感兴趣的列表:

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 回答