0

如果您对如何修改问题标题以使其更具描述性有任何建议,请随时提出。

假设您有一个返回对象的类方法,是否有最佳实践或标准方法在该方法中创建对象的位置?为了澄清,请参见下文:

public MyCustomObject myMethod(String arg1, String arg2){
    try{
        if (something){
            ...
        } else {
            ...
        }
    } catch ( SomeException e ){
        ...
    } catch ( SomeOtherException e ){
        ...
    }

    return myCustomObject;
}

MyCustomObject 有一个空构造函数,一个具有 5 个字段和 getter/setter 的构造函数。在上述(简化)流程的每种情况下,我都需要返回一个有效的 MyCustomObject 。请不要专注于控制流本身。

我认为我可以: a) 在方法的开头使用 null 初始化 MyCustomObject 类型的变量。为控制流中的每个不同情况分配一个新的 MyCustomObject。最后归还。b) 在开始时使用空构造函数实例化一个 MyCustomObject。使用流中每个案例的设置器修改对象。

你能想出为什么上述一种或不同的方式更可取的原因吗?

谢谢

4

4 回答 4

2

我更喜欢您没有提到的选项 3:为控制流中的每个不同情况创建一个新的 MyCustomObject,并立即返回它。不需要变量,通常:

if (foo) {
    return new MyCustomObject("foo");
}
if (bar) {
    return new MyCustomObject("x", "y");
}
// etc

这通常以更少的嵌套结束,并且更容易阅读,因为只要你点击return语句,你就完成了。

有些人坚持只有一个出口点的教条,但我认为这些天这有点毫无意义——这在你需要在返回之前进行清理的语言中是有意义的,但需要垃圾收集和finally其他资源的块清理,没必要。

如果您尽快返回,您通常可以在代码中减少嵌套 - 这大大提高了可读性。

于 2012-10-20T18:21:18.260 回答
0

所以要么:

MyCustomObject result = null;
if (something) {
    result = new MyCustomObject(a, b, c, d, e);
} else {
    result = new MyCustomObject(a, b, x, y, z);
}

或者

MyCustomObject result = new MyCustomObject();
if (something) {
    result.Name = arg1;
} else {
    result.Phone = arg2;
}

return result;

?

我真的不明白为什么我应该选择一个而不是另一个!我可能会使用 B 来确保我没有忘记初始化结果……但这并不是一个很好的理由。

于 2012-10-20T18:15:21.763 回答
0

在我的工作中,我个人更喜欢第一种方法(即,声明返回变量,将其分配给null,然后允许程序的实际逻辑根据需要实例化适当的对象)。

我发现这更有用的原因是因为无论您从哪里调用该方法,都可能想知道创建对象时是否出现问题,或者是否创建了有用的对象。执行空检查比尝试确定实例化对象是否是虚拟对象要容易得多。您会发现空值检查通常是复杂程序控制流的重要组成部分。如果我总是返回一个对象,无论发生什么,我的检查器都必须更复杂。

例如,假设我有一个readItem()返回自定义Item对象的方法。在这种情况readItem()下,它会从表中获取一些数据并Item用它填充。现在,假设处理过程中没有出现任何问题readItem(),保证抛出异常,但Item我们想要读取的标准根本不在表中(例如,也许我们提供了一个不存在项目的项目 ID 或其他东西)。然后,如果我返回一个实例化Item而不是null,这将更难弄清楚。

于 2012-10-20T18:15:47.193 回答
0

选项1:

MyCustomObject myCustomObj = null;

for( index > list of cases ){

    myCustomObj = myMethod(param1, param2);

}

完美:您声明了一次变量并修改了值。

选项 2:

for( index > list of cases ){

    MyCustomObject myCustomObj = myMethod(param1, param2);

}

好:您一次又一次地重新声明变量并修改值。

选项 3:

MyCustomObject myCustomObj = new MyCustomObject();

for( index > list of cases ){

    myCustomObj = myMethod(param1, param2);

}

坏:你在第一行浪费内存,因为引用没有被使用。但仍然没有造成伤害

于 2012-10-20T18:15:58.263 回答