返回通用结果

时间:2019-04-25 22:41:48

标签: java oop

说我有一个查看文件并返回两个结果的函数:可识别和不可识别。当它返回识别的结果时,我希望结果也包含一条消息,但是当它未被识别时,则不需要任何消息。

public Result checkFile(File file) {
    ...
}

我可以想到两种方法来实现这一目标...

具有Result类,如下所示:

class Result {

    private Type type;
    private String message;

    enum Type { 
        RECOGNIZED, UNRECOGNIZED
    }

}

或者这样做:

class Result {
}

class Unrecognized extends Result {
}

class Recognized extends Result {
    private String message;
}

我倾向于使用第二种方法,即使我不得不使用instanceof检查结果,并且我已经阅读到应该尽可能避免使用instanceof,但是这样做可以避免无法识别结果时显示空消息。对于此示例,空消息不是什么大问题,但是如果有更多的数据与可识别的结果相关联该怎么办?对我来说,实例化一个可能具有所有空字段的类似乎是更糟糕的做法。

处理这种情况的最佳实践是什么?有一些标准的方法或模式吗?

5 个答案:

答案 0 :(得分:2)

两个类可能是过大的,因为它是一个并且是同一类对象。另外,不需要带有两个值的enum,而这两个值只能重新组合truefalse。一个class Result就足够了,这也将消除对公用interface的需求。我将全力以赴:“没有必要的复杂性” ...

class RecognitionResult {

    private String message = "default message";
    private boolean recognized = false;

    public Result() {}

    public Result(boolean value) {
        this.setRecognised(value);
    }

    public boolean setRecognised(boolean value) {
        this.recognized = value;
    }

    public boolean setMessage(@NonNull String value) {
        this.message = value;
    }

    public boolean getRecognised() {
        return this.recognized;
    }

    @Nullable
    public String getMessage() {
        return this.recognized ? this.message : null;
    }
}

那么一个人就可以做到:

return new RecognitionResult(true);

用于异步回调的interface可能看起来像这样:

interface Recognition {
    void OnComplete(RecognitionResult result);
}

或者如果您真的想优化:

interface Recognition {
    void OnSuccess(RecognitionResult result);
    void OnFailure(RecognitionException e);
}

答案 1 :(得分:1)

当然,这里没有“正确”的设计-哪种方法会成问题。但是,我认为OOD的现代趋势是最小化扩展的使用,并尽可能使用接口的委派和实现。

作为一般规则,每当您考虑使用instanceof时,都要重新考虑您的设计。

这是我的建议:

interface Result {
    boolean isRecognised();
    String getMessage();
}

class RecognisedResult implements Result {
    private final String message;

    public boolean isRecognised() {
        return true;
    }

    public String getMessage() {
        return message;
    }
}

class UnrecognisedResult implements Result {
    public boolean isRecognised() {
        return false;
    }

    public String getMessage() {
        throw new UnsupportedOperationException("No message for unrecognised results");
    }
}

答案 2 :(得分:0)

您可以查看翻新实施“公认”和“消息”概念的方式 https://square.github.io/retrofit/2.x/retrofit/retrofit2/Response.html。它类似于您的第一种方法。

他们要做的是拥有一个名为Response的类,其中包含一个名为isSuccessful()的方法,以及一个名为body()的方法,如果该方法成功,则该方法包含有效载荷(如果不成功,则为null。

您可以尝试以下操作

class Result {

    private Type type;
    private String message;

    public bool isSuccessful(){
            return type == RECOGNIZED;
    }

    public String getMessage(){
            return message; //null if unrecognized.
    }

    enum Type { 
        RECOGNIZED, UNRECOGNIZED
    }

}

答案 3 :(得分:0)

您可以使用Java的Optional类型,如果无法识别内容,则返回library(tidyverse) df1 = df %>% rowid_to_column('row') %>% gather(key, value, -row) head(df1) row key value 1 1 fish 2.3 2 2 fish 2.6 3 3 fish 4.3 4 4 fish 1.3 5 1 rice 3.4 6 2 rice 3.5 # group is needed to tell ggplot which points to connect in each line ggplot(df1, aes(x = key, y = value, color = factor(row), group = row)) + geom_line() ,如果可以识别内容,则返回Optional.empty()。然后,您不需要Optional.of(new Result(...))类型的枚举。

Result

答案 4 :(得分:0)

实现此功能的方法是使用Either类型,它不是JDK附带的,但在vavr库中可用。根据您对该线程的评论,您似乎不太清楚类型继承的工作原理。在这种情况下,功能性解决方案可能会过大,我建议使用@sprinter的solution