在Java中返回多个值的最佳实践?

Tin*_*Sky 29 java return function

今天我在登录表单后面添加了额外的安全检查,以减缓暴力攻击.我有多个登录表单,并且做了一个很好的易于调用的函数,它执行所有检查,然后返回结果.

public static ValidateLoginResult validateLogin(HttpServletRequest request, String email, String password) {
Run Code Online (Sandbox Code Playgroud)

问题是结果不是单个值,结果包括:

boolean ok
String errorMessage
boolean displayCaptcha
Run Code Online (Sandbox Code Playgroud)

为此我创建了一个新类.一切正常.

但是我经常有一些方便的实用程序函数返回多个值,并且开始发现每次为结果创建一个新类有点烦人.

有没有更好的方法来返回多个值?还是我只是懒惰?:)

gma*_*gma 16

不,这种结构在Java中并不存在,但您可以查看可能适合您需求的JavaTuples库,并提供一个非常优雅的解决方案.用一个Triplet<Boolean, String, Boolean>

  • 写`return new Triplet <布尔,字符串,布尔>(实际值)`不是优雅的光辉典范,要么:) (9认同)
  • 因此,如果返回Triplet对象的方法现在需要返回可选的第4位数据,则​​必须将返回类型从Triple更改为Quartet?不用了,谢谢.我宁愿滚动一个ReturnObject,我可以在不破坏客户端代码的情况下添加另一个属性. (6认同)

Bri*_*ian 5

不确定"最佳实践",但务实的选择是返回Map<String, String>?例如

myMap.put("result", "success");
myMap.put("usernameConfirmed", "bigTom");

return myMap;
Run Code Online (Sandbox Code Playgroud)

面对百万OO原则可能会飞,但我听说你想避免结果类的扩散.

您也可以使用Map<String, Object>并更严格地对存储对象进行类型检查:字符串,布尔值,日期等.

  • 如果使用Enum作为键值,则可以避免拼写错误和自我文档. (4认同)

Rai*_*baz 5

我真的想不出比将它们封装在类中更好、更干净、更面向对象的从函数返回多个值的方法。

理想情况下,您想要返回的多个值在概念上都是同一类的一部分,因此以这种方式对它们进行分组是有意义的;如果没有,那么您可能应该将函数分解为一些较小的函数,这些函数返回函数本身之外所需的每个值。

据我所知,一些 IDE 还具有帮助在类中封装多个值的功能:例如,Eclipse 有Refactor --> Extract class...

  • 这与面向对象无关;主要是关于 Java 的静态类型和弱泛型。JavaScript 是面向对象的,不需要为每个元组创建另一个类。 (3认同)

tuc*_*uxi 5

您可以定义一个Pair<A, B>类和一个Triplet<A, B, C>类,这将解决返回2和3值同时确保类型安全的问题.在这种特殊情况下,签名可以是

public static boolean validateLogin(HttpServletRequest request,
            String email, String password, Pair<Message, Boolean> outputIfOk);
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,在servlet上下文中,设置一些记录良好的请求属性可能是有意义的.

如果您发现自己需要特殊的类来经常返回结果,那么您很可能会重构这些条款以共享共同的祖先(例如,有一个包含'ok'和'message'字段的RequestStatus).

除此之外,是的,你是懒惰的 - 自定义契约总是比双人和三胞胎更自我记录.