在Java中处理具体类型时的替代方法

Wic*_*koo 6 java inheritance instanceof

假设我有以下类层次结构:

public interface Result {
}
public class Failure implements Result {
    private String msg;
    public Failure(String msg) {
        this.msg = msg;
    }
    @Override public String toString() { return msg; }
}
public class Success implements Result {
    private int time, count;
    public Success(int time, int count) { this.time = time; this.count = count; }
    public int getTime() { return time; }
    public int getCount() { return count; }
    @Override public String toString() { return time + ", " + count; }
}
Run Code Online (Sandbox Code Playgroud)

它基本上定义了一个具有两个具体类的接口Result:Success和Failure.

然后,我有一个计算方法返回一个结果,并根据结果我应该做一些事情,例如:

Result result = calculate();
Run Code Online (Sandbox Code Playgroud)

我有几个选项来弄清楚具体的课程.最明显的一个是使用以下实例:

if (result instanceof Success) {
    int time = result.getTime();
    int count = result.getCount();
    // Do something with them
} else {
    throw new RuntimeException(result.toString());
}
Run Code Online (Sandbox Code Playgroud)

在像Scala这样支持模式匹配的编程语言中,我可以使用类似的匹配

case Success =>
case Failure =>
Run Code Online (Sandbox Code Playgroud)

但由于Java不支持它,我不确定什么是最好的.我可以例如扩展Result接口,如下所示:

public interface Result {
    public boolean isSuccess();
    public boolean isFailure();
    public Success asSuccess();
    public Failure asFailure();
}
Run Code Online (Sandbox Code Playgroud)

然后将客户端代码写为:

if (result.isSuccess()) {
   Success success = result.asSuccess();
   int time = success.getTime();
   int count = success.getCount();
   // Do something with them
} else {
   throw new RuntimeException(result.toString());
}
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,接口绑定到具体的类,这也是不好的.

表示此类案件的最佳方式是什么?我真的不想将处理代码放在Result层次结构中,因为它实际上取决于客户端获取数据并做任何他们想做的事情,因此多态调度解决方案可能不是最好的.结果层次结构充其量只是数据类型封装,而不是操作.

Nim*_*sky 0

这可以简化为

public interface Result {
  public boolean isSuccess();
  public Integer getTime();
  public Integer getCount();
}
Run Code Online (Sandbox Code Playgroud)

您必须实现失败的计数和时间(返回零/空或抛出异常),然后:

if (result.isSuccess()) {
  int time = result.getTime();
  int count = result.getCount();
  // Do something with them
} 
else {
  throw new RuntimeException(result.toString());
}
Run Code Online (Sandbox Code Playgroud)

您不需要在接口上使用 toString,但您可能需要这样做,因为它明确地告诉其他开发人员担心将来是否会实现另一个结果(BigSuccess、MssvieFail 等)。

表示成功的布尔值似乎简单且直观。