【发布时间】:2014-10-10 13:59:36
【问题描述】:
我在跨多个模块扩展访问者模式时遇到问题,您可以阅读 cmets 中的问题说明。
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() 方法放在 ISource 中 不会有这样的问题,但我想这也不是完美的方式。
问题是我们可以对访客做得更好吗?
或者在这种情况下您建议的方法是什么?
【问题讨论】:
-
您可以对基本访问者使用一些默认操作:打印日志条目和/或抛出异常以在其他地方处理。为什么你认为有更好的选择?
-
因为我认为外面有比我更聪明的人=),我也考虑过例外但我们会等待,也许有人会想出另一个主意。
-
好吧,让代码在没有 CCE 的情况下工作的一种选择:
class Module2Source2 extends Module1Source1 implements IAnotherModuleSource。但我不知道你是否可以接受。 -
与问题无关,但尽管有 Wikipedia 的示例,但现代高级语言中普遍放弃了匈牙利符号。
标签: java design-patterns visitor-pattern extensibility