如何在访问者模式中使用已检验的异常
2022-09-03 02:31:48
假设我有一套接受访问者(访问者模式)的类,但由于这些类或特定访问者的性质,对它们执行工作可能会引发检查异常。
访客接受界面:
public interface Mammal
{
void accept(MammalVisitor visitor);
}
访客界面:
public interface MammalVisitor
{
void visit(Cat m);
void visit(Dog m);
void visit(Cow m);
}
哺乳动物的实现:
public class Cat implements Mammal
{
public void accept(MammalVisitor visitor)
{
visitor.visit(this);
}
}
我们假设Dog & Cow的实现与Cat相同
现在假设我的访客是:
public class MammalPrinter implements MammalVisitor
{
private final Appendable out;
public MammalPrinter(Appendable out)
{
this.out = out;
}
@Override
public void visit(Cat m)
{
out.append("I'm a cat");
}
@Override
public void visit(Dog m)
{
out.append("I'm a dog");
}
@Override
public void visit(Cow m)
{
out.append("I'm a cow");
}
}
我将结果打印到 stdio:
Mammal m = MammalFactory.getMammal();
MammalPrinter mp = new MammalPrinter(System.out);
m.accept(mp);
但是,上面的 MammalPrinter 在语法上是不正确的,因为 Appendable.append(String) 会抛出 。我无法在每个访问方法上声明 throw,因为它未在访问者接口中声明。java.io.IOException
我考虑过的解决方案:
- 声明 on 、所有三个和所有三个
throws IOException
Mammal.accept()
MammalVisitor.visit()
MammalPrinter.visit()
- 非常令人讨厌:哺乳动物和哺乳动物访问器接口现在意识到它们的潜在用途涉及IO,这与使用访问者模式的全部意义相反。
- 声明 on 和 all 三个,并在所有三个上声明
throws Throwable
Mammal.accept()
MammalVisitor.visit()
throws IOException
MammalPrinter.visit()
- 比上述解决方案更好:哺乳动物和哺乳动物访客现在与用法无关。但是,它们现在使用起来也很笨拙:没有抛出异常的访问者仍然被迫从 accept() 方法处理 Throwable。
与上述相比,我还有另外两种解决方案,我将用它们自我回答我的帖子。我想看看哪一个受到整个社区的青睐。