我有2个对象:Protocol
和Server
。第一个是通知Server
不同的对象,Server
应该根据对象的类型执行操作。所以,对我来说完美的选择是:
// Server.java
public Server implements IObserver {
public void onAction(ActionObjectOne o) {
//do magic
}
public void onAction(ActionObjectTwo o) {
//do magic
}
....
}
// Protocol.java
public Protocol extends AObservable {
// ....
notifyObservers(ActionObjectOne one);
// ...
}
所以我认为这是观察者模式的工作。
public interface IObserver {
<T extends IAction> void onAction(T action);
}
public class Server implements IObserver {
@Override
public <AuthAction> void onAction(AuthAction action) {
// HERE IS A PROBLEM
}
}
public class AuthAction extends Action; // Action implements IAction - a flag-interface
错误在Server
:
那么,如何实现我的“完美选择”=)?
答案 0 :(得分:1)
使用以下语法
public <AuthAction> void onAction(AuthAction action) {
表达式AuthAction
是一个类型变量,而不是类型参数。上面的代码相当于
public <T> void onAction(T action) {
因此,您可以看到您的Server
课程没有实现IObserver
的方法。我会改为使IObserver
成为通用接口并像这样实现它
public interface IObserver<T extends IAction> {
void onAction(T action);
}
class Server implements IObserver<AuthAction> {
@Override
public void onAction(AuthAction action) {
}
}
答案 1 :(得分:0)
您可以这样做:
public void update(Observable o, Object arg) {
try {
Method update = getClass().getMethod("onAction", arg.getClass());
update.invoke(this, arg);
} catch (NoSuchMethodException e) {
LOGGER.error("No onAction for <" + arg.getClass().getSimpleName() + "> action.");
LOGGER.catching(e);
} catch (Exception e) {
LOGGER.catching(e);
}
}
and then:
public void onAction (AuthAction action) {
System.out.println("New user incoming!");
}
答案 2 :(得分:0)
IAction
的集合是有限的,不变的,可管理的吗?如果是这样,您的Observer更像是一个访问者,并且需要为每个已知操作重载。
如果IAction
的集合并非所有这些内容,但调用者知道静态传递了哪种IAction
,那么您定义的IObserver
接口是正确的。也就是说,接口的实现者(例如Server
)应该动态地对特定的IAction
类做出反应,使用Java中的任何一些非常丑陋的选择来做如此。
public interface IObserver {
void < T extends IAction > onAction( T action );
}
public class Server implements IObserver {
@Override public void < T extends IAction > onAction( T action ) {
// ugliness, e.g. if-ladders based on instanceof
}
}
我认为这不会给你买得太多。
如果调用者不知道在运行时将使用哪个IAction
,那么您唯一的选择是
public interface IObserver {
void onAction( IAction action );
}
public class Server implements IObserver {
@Override public void onAction( IAction action ) {
// ugliness, e.g. if-ladders based on instanceof
}
}
其实现与前一个示例中的实现相同。