0
我有一个问题来扩展访问者模式跨多个模块,你可以阅读评论中的问题的解释。在不修改原始源代码的情况下扩展访问者模式?
interface Example {
interface ISource {
Object accept(ISourceVisitor visitor);
}
class Module1Source1 implements ISource {
@Override
public Object accept(ISourceVisitor visitor) {
return visitor.visit(this);
}
}
class Module1Source2 implements ISource {
@Override
public Object accept(ISourceVisitor visitor) {
return visitor.visit(this);
}
}
interface ISourceVisitor {
Object visit(Module1Source1 wheel);
Object visit(Module1Source2 engine);
}
class SupportedCurrenciesVisitor implements ISourceVisitor {
@Override
public Object visit(Module1Source1 wheel) {
return ImmutableList.of("USD");
}
@Override
public Object visit(Module1Source2 engine) {
return ImmutableList.of("EUR");
}
}
//suppose we don't want to change the code above because it's in another library
//I want to add one more source
class Module2Source1 implements ISource {
@Override
public Object accept(ISourceVisitor visitor) {
return null;
}
}
// I cannot change ISourceVisitor, so what do I need to do?
// one way is to create another interface
interface IAnotherModuleSource extends ISource {
Object accept(IThisModuleSourceVisitor visitor);
}
interface IThisModuleSourceVisitor extends ISourceVisitor {
Object visit(Module2Source2 module2Source2);
}
class Module2Source2 implements IAnotherModuleSource {
//it's ok
@Override
public Object accept(IThisModuleSourceVisitor visitor) {
return visitor.visit(this);
}
//but what should we do with this:??
@Override
public Object accept(ISourceVisitor visitor) {
return accept((IThisModuleSourceVisitor) visitor);
}
//this way if SupportedCurrenciesVisitor will be passed to the Module2Source2 we
//will have CCE
//but it's ok if we pass here specific visitor for this module
}
}
很显然,如果我们将放置方法getSupportedCurrencies()在东森光电 就不会有这样的问题,但它也没有我想完美的方式。
问题是,我们可以做更好的访客吗?
或者在这种情况下你会采取什么建议?
您可以对基本访问者使用一些默认操作:打印日志条目和/或抛出异常以在其他地方处理。为什么你认为有更好的选择? – 2014-10-10 14:27:05
因为我认为有人比我更聪明=),我也考虑过例外,但我们会等待,也许有人会想出另一个想法。 – 2014-10-10 14:37:07
那么,一个选项可以使代码无需CCE:'Module2Source2 extends Module1Source1 implements IAnotherModuleSource'。但我不知道它是否可以接受。 – 2014-10-10 14:42:26