fns*_*nst 63 java oop instanceof
我有以下(可能是常见的)问题,现在绝对让我困惑:
有几个生成的事件对象扩展了抽象类Event,我想将它们分成Session Bean,比如
public void divideEvent(Event event) {
if (event instanceof DocumentEvent) {
documentGenerator.gerenateDocument(event);
} else if (event instanceof MailEvent) {
deliveryManager.deliverMail(event);
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
但是将来可能会有两种以上的事件类型,所以if-else将会很长并且可能无法读取.此外,我认为instanceof在这种情况下并不是真正的"最佳实践".
我可以在Event类型中添加一个抽象方法并让它们自行划分但是我必须在每个实体中注入特定的会话Bean.
是否有任何暗示可以为这个问题实现"漂亮"的解决方案?
谢谢你的帮助!
Pet*_*rey 54
最简单的方法是让Event提供一个可以调用的方法,以便Event知道该怎么做.
interface Event {
public void onEvent(Context context);
}
class DocumentEvent implements Event {
public void onEvent(Context context) {
context.getDocumentGenerator().gerenateDocument(this);
}
}
class MailEvent implements Event {
public void onEvent(Context context) {
context.getDeliveryManager().deliverMail(event);
}
}
class Context {
public void divideEvent(Event event) {
event.onEvent(this);
}
}
Run Code Online (Sandbox Code Playgroud)
Cha*_*tin 11
多态性是你的朋友.
class DocumentGenerator {
public void generate(DocumentEvent ev){}
public void generate(MainEvent ev){}
//... and so on
}
Run Code Online (Sandbox Code Playgroud)
然后就是
DocumentGenerator dg = new DocumentGenerator();
// ....
dg.generate(event);
Run Code Online (Sandbox Code Playgroud)
更新
许多人提出反对意见,"你必须在编译时知道各种事件." 而且,是的,您显然必须知道您在生成器部件的编译时要解释的事件,否则您何时可以编写生成部件?
这些竞争示例使用Command模式,这很好,但意味着事件不仅要知道它们的表示细节,还要知道如何打印它们的表示.这意味着每个类可能有两种需求变化,它们的敏感性:事件所代表的变化,以及事件在打印中的表示方式的变化.
现在,考虑一下,例如,需要将其国际化.在命令模式的情况下,你必须去ñ类ň不同的事件类型,并写入新做的方法.在多态性的情况下,更改被本地化为一个类.
当然,如果您需要进行一次国际化,您可能需要多种语言,这会促使您在Command-pattern案例中为每个类添加类似策略的内容,现在需要n个类× m种语言; 再次,在多态性情况下,您只需要一个策略和一个类.
有理由选择任何一种方法,但声称多态方法是错误的只是不正确.