Java中观察者模式的重命名实现方法
我使用Java中的Observable类/观察者接口来实现观察者模式。Observer接口需要覆盖更新(Observable o,Object arg)方法 问题是我观察到了相当多的类,我的update()方法变得非常大:Java中观察者模式的重命名实现方法,java,design-patterns,observer-pattern,observable,Java,Design Patterns,Observer Pattern,Observable,我使用Java中的Observable类/观察者接口来实现观察者模式。Observer接口需要覆盖更新(Observable o,Object arg)方法 问题是我观察到了相当多的类,我的update()方法变得非常大: public class Foo implements Observer { .... public void update(Observable o, Object param) { if (o instanceof A) {
public class Foo implements Observer {
....
public void update(Observable o, Object param) {
if (o instanceof A) {
// large chunk of code
...
} else if (o instanceof B) {
// large chunk of code
...
}
...
} else if (o instanceof H) {
...
}
}
}
为了分解该方法,我正在考虑使用AObserver接口、BObserver接口等扩展Observer接口。。需要覆盖OnUpdate、onBUpdate。。分别地此方法还可以根据类所实现的接口轻松确定类所观察到的可观察对象
class Foo implements AObserver, BObserver {
....
public void onAUpdate(Observable o, Object param) {
if (o instanceof A) {
// large chunk of code
...
}
public void onBUpdate(Observable o, Object param) {
if (o instanceof B) {
// large chunk of code
...
}
}
问题是,如果我继承了Observer,我仍然必须实现update()方法。我无法将其重命名为OnUpdate或我选择的其他名称
有什么建议吗?谢谢。将每个条件中的代码块移动到适当命名的方法中
public void update(Observable o, Object param) {
if (o instanceof A) {
onAUpdate(o, param);
}
if (o instanceof B) {
onBUpdate(o, param);
}
}
public void onAUpdate(Observable o, Object param) {
// large chunk of code
}
public void onABUpdate(Observable o, Object param) {
// large chunk of code
}
我建议创建一个UpdateHandler接口来处理任何给定的代码块。每个案件都可以用地图来处理 示例代码如下:
// Interface to implement for each case
public interface UpdateHandler {
public void update(Observable source, Object data) ;
}
将实例字段添加到主类中,如下所示:
private Map<Class<?>, UpdateHandler> handlers = new HashMap<Class<?>, Update Handler>();
updates方法只需找到适当的处理程序并分派调用
public void update(Observable source, Object data)
{
UpdateHandler handler = handlers.get(data.getClass()) ;
if (handler == null)
{
// use a default handler ? throw an exception ? your choice ;)
} else {
handler.update(source, data) ;
}
}
此实现将允许您根据需要添加新的处理程序,只需进行最小的更改
另一个可能的实现可以在前面工作的基础上完成,只需3个步骤
1) 更改处理程序字段的声明
Map<Class<?>, Class<? extends UpdateHandler>> handlers ;
3) 更改主更新方法以创建所提供的UpdateHandler实现的新实例
UpdateHandler handlerInstance = null ;
Class<? extends UpdateHandler> handler = null ;
handler = handlers.get(data.getClass()) ;
...
handlerInstance = handler.newInstance() ;
handlerInstance.update(source, data) ;
UpdateHandler-handlerInstance=null;
类在这里,我使用观察者和访问者模式编写了一个原始实现。你可以把这当作一个想法来加强它,并填补任何你看到的漏洞
public interface IObserver extends Observer {
public void add(AbstractObservable observable, IObserverVisitor visitor);
public void remove(AbstractObservable observable);
public void removeAll();
}
我希望你没有迷路。:)是否可以为每个可观察对象实现一个接口?当我的类实现AObserver、BObserver时,确定它感兴趣的对象就变得更加清晰了。。。而不仅仅是一个普通的观察者,这是他最初所做的。您刚才建议将块取出以分离方法。代码仍然有味道。他说问题在于“我的update()方法变得非常大”。@david:你可以说是杀伤力太大了。或者,您可以编写一些有效的、不受性能影响的、模块化的和可维护的东西。如果您可以将update
方法推到(抽象)基类中,则可以使其更加优雅,以及onUpdate
方法的抽象或默认实现。我有多个对象观察可观察对象。当一些有趣的事情发生时,每个关注可观察对象的类的行为都不同。例如,如果Foo和Bar都观察A,那么当A发生变化时,Foo做这个,Bar做那个。使用此解决方案,是否意味着我必须为每个对象创建一个处理程序来分别处理更新,例如FooAHandler、BarAHandler?@David:如果是这样的话,您不需要任何特殊的东西。默认的Observable
和Observable
将执行此操作。在您的原始帖子中,您正在检查您的可观察的
类型,这表明单个观察者
正在观察多个可观察的
。这是一种多对多关系-多个观察者正在观察多个可观察的。谢谢,这是一个很好的解决方案。我不确定它是否直接适合我的情况,我可能需要调整一些部分,但它给了我一些好主意。@David:很高兴你发现它很有用。我的努力没有白费
UpdateHandler handlerInstance = null ;
Class<? extends UpdateHandler> handler = null ;
handler = handlers.get(data.getClass()) ;
...
handlerInstance = handler.newInstance() ;
handlerInstance.update(source, data) ;
public interface IObserver extends Observer {
public void add(AbstractObservable observable, IObserverVisitor visitor);
public void remove(AbstractObservable observable);
public void removeAll();
}
public class Observer implements IObserver {
Map<AbstractObservable, IObserverVisitor> observableMap =
new HashMap<AbstractObservable, IObserverVisitor>();
public void add(AbstractObservable observable, IObserverVisitor visitor) {
observableMap.put(observable, visitor);
}
public void remove(AbstractObservable observable) {
observableMap.remove(observable);
}
public void removeAll() {
observableMap.clear();
}
public void update(Observable o, Object arg) {
observableMap.get(o).visit(this, o, arg);
}
}
public class AbstractObservable extends Observable{
public synchronized void addObserver(IObserver o, IObserverVisitor visitor) {
o.add(this, visitor);
super.addObserver(o);
}
public synchronized void deleteObservers(IObserver o) {
o.removeAll();
super.deleteObservers();
}
public synchronized void deleteObserver(IObserver o) {
o.remove(this);
super.deleteObserver(o);
}
@Override
public synchronized void deleteObserver(Observer o) {
throw new UnsupportedOperationException();
}
@Override
public synchronized void addObserver(Observer o) {
throw new UnsupportedOperationException();
}
@Override
public synchronized void deleteObservers() {
throw new UnsupportedOperationException();
}
@Override
public synchronized int countObservers() {
return super.countObservers();
}
@Override
public synchronized boolean hasChanged() {
return super.hasChanged();
}
@Override
public void notifyObservers() {
super.notifyObservers();
}
@Override
public void notifyObservers(Object arg) {
super.notifyObservers(arg);
}
@Override
protected synchronized void clearChanged() {
super.clearChanged();
}
@Override
protected synchronized void setChanged() {
super.setChanged();
}
}
public class Observable1 extends AbstractObservable {
public void changeSomething() {
setChanged();
notifyObservers();
}
}
public class Observable2 extends AbstractObservable {
public void changeSomething() {
setChanged();
notifyObservers();
}
}
public interface IObserverVisitor {
void visit(IObserver obsrvr, Observable obsrvable, Object o);
}
public class ObserverVisitor1 implements IObserverVisitor{
public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
System.out.println("updated one");
}
}
public class ObserverVisitor2 implements IObserverVisitor{
public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
System.out.println("updated two");
}
}
public class ObserverTest {
@Test
public void testAnything() {
Observable1 obsrvable1 = new Observable1();
Observable2 obsrvable2 = new Observable2();
Observer obsrvr = new Observer();
obsrvable1.addObserver(obsrvr, new ObserverVisitor1());
obsrvable2.addObserver(obsrvr, new ObserverVisitor2());
obsrvable1.changeSomething();
obsrvable2.changeSomething();
}
}