我正在寻找以下问题的设计模式/解决方案,这与观察者模式有关,我已经研究过了。
在我的代码中,我有一个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 Generics?)某些监听器只对Flowers
感兴趣,有些只关注Toys
等?
那么如何设计支持监听某些属性的类结构?
所有听众无论如何都会为操作添加,更新和删除实施3种方法。
答案 0 :(得分: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() { ....}
}
并且每个属性的任何更改都会反映给相关的侦听器。
<强>更新强>
另一个解决方案是你有一个感兴趣的列表 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() { ... }
}
a in model:
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() { ... }
}
答案 1 :(得分:1)
如何应用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
您还可以将各个属性的更新例程移动到属性本身。