我使用Java中的可观测类/ Observer接口来实现观察者模式。该观察接口需要重写更新(可观察到O,对象ARG)方法

的问题是,我观察的班级相当数量的,我的update()方法已经得到了非常大的:

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

}

为了分裂的方法中,我想延伸与例如Observer接口的AObserver接口,BObserver接口..这需要重写onAUpdate,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
        ...
    }
}

的问题是,如果我继承观察,我仍然必须实现update()方法。我不能把它重命名为onAUpdate或我选择的其他名称。

任何意见?感谢。

有帮助吗?

解决方案

下面我编码使用观测器和访问者模式原料实现。你可以把这个作为一个想法后,它增强和填补无论你看到一些漏洞。

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

}

我希望你不会丢失。 :)

其他提示

我会建议创建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>();

创建方法有处理程序初始化

protected void initializeHandler() {
    handler.put(Integer.class, new IntegerUpdateHandler());
    handler.put(String.class, new StringUpdateHandler());
    ...
}

在更新方法将简单地找出合适的处理程序并调度呼叫

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 ;

2)改变初始化方法

handlers.put(Integer.class, IntegerInputHandler.class);

3)改变主更新方法来创建提供UpdateHandler实施的新实例。

UpdateHandler handlerInstance = null ;
Class<? extends UpdateHandler> handler = null ;
handler = handlers.get(data.getClass()) ;
...
handlerInstance = handler.newInstance() ;
handlerInstance.update(source, data) ;

移动的代码块的每个状态内,以适当命名方法。

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
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top