1
假設我們有以下的,我們不能改變類:爪哇 - 從顧客返回的值
interface Base {
void accept(Visitor visitor);
}
class Foo implements Base {
short getShortValue() {
return 1;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Bar implements Base {
int getIntValue() {
return 2;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
interface Visitor {
void visit(Foo foo);
void visit(Bar bar);
}
,我們需要實現的方法:
int getValue(Base base)
有很多可能性去做與訪客使用一些存儲對象:
int useArray(Base base) {
int[] result = new int[1];
base.accept(new Visitor() {
@Override
public void visit(Foo foo) {
result[0] = foo.getShortValue();
}
@Override
public void visit(Bar bar) {
result[0] = bar.getIntValue();
}
});
return result[0];
}
int useAtomic(Base base) {
AtomicInteger result = new AtomicInteger();
base.accept(new Visitor() {
@Override
public void visit(Foo foo) {
result.set(foo.getShortValue());
}
@Override
public void visit(Bar bar) {
result.set(bar.getIntValue());
}
});
return result.intValue();
}
int useMutable(Base base) {
MutableInteger result = new MutableInteger(0);
base.accept(new Visitor() {
@Override
public void visit(Foo foo) {
result.setValue(foo.getShortValue());
}
@Override
public void visit(Bar bar) {
result.setValue(bar.getIntValue());
}
});
return result.getValue();
}
或者變態的東西:
int useException(Base base) {
class GotResult extends RuntimeException {
private final int value;
public GotResult(int value) {
this.value = value;
}
}
try {
base.accept(new Visitor() {
@Override
public void visit(Foo foo) {
throw new GotResult(foo.getShortValue());
}
@Override
public void visit(Bar bar) {
throw new GotResult(bar.getIntValue());
}
});
} catch (GotResult result) {
return result.value;
}
throw new IllegalStateException();
}
或者不使用訪客都:
int useCast(Base base) {
if (base instanceof Foo) {
return ((Foo) base).getShortValue();
}
if (base instanceof Bar) {
return ((Bar) base).getIntValue();
}
throw new IllegalStateException();
}
現在這些是我們唯一的選擇嗎?我們有Java 8(很快就會有9個),並且仍然在寫這些容易出錯的代碼。 :)