我有一个问题是在多个模块中扩展访客模式,您可以在评论中阅读问题的解释。
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中 没有这样的问题,但我认为这也不是完美的方式。
问题是我们可以通过访问者做得更好吗?
或者在这种情况下你建议的做法是什么?
答案 0 :(得分:1)
Tl; dr:您所描述的问题是尝试将模式应用于不适合的问题。
“改变的原因”全部分为两大类:数据和功能。访问者模式将数据和功能之间的正常OO直接关联分离,使您能够牺牲更改数据结构的能力,以便能够非常轻松地更改功能。添加另一个ISourceVisitor
是微不足道的,因为访问者模式的目的就是让你这样做。添加另一个ISource
会更改您的数据结构并强制您更改所有功能以适应它,这肯定表明您选择了错误的模式。