以我的拙见,您应该考虑三种退货情况:
对象属性操作
首先是对象属性的操作。您在此处描述的模式在操作对象时经常使用。一个非常典型的场景是与工厂一起使用它。考虑这个假设的创建调用:
// When the object has manipulative methods:
Pizza p = PizzaFactory().create().addAnchovies().addTomatoes();
// When the factory has manipulative methods working on the
// object, IMHO more elegant from a semantic point of view:
Pizza p = PizzaFactory().create().addAnchovies().addTomatoes().getPizza();
它允许快速掌握正在创建的确切内容或如何操作对象,因为这些方法形成了一个人类可读的表达式。这绝对不错,但不要过度使用。一个经验法则是,这可能与返回值也可以声明为 void 的方法一起使用。
评估对象属性
第二个可能是当方法评估对象上的某些内容时。例如,考虑方法car.getCurrentSpeed()
,它可以被解释为向对象询问当前速度并返回该消息的消息。它只会返回值,不会太复杂。:)
让对象做这个或那个
第三个可能是当一个方法执行一个操作时,返回某种值,表明调用者的意图被实现的程度——但布局这样的方法可能很困难:
int new_gear = 20;
if (car.gears.changeGear(new_gear)) // does that mean success or fail?
这是您可以看到设计该方法的困难之处。它应该在成功还是失败时返回 0?如果无法设置档位,-1 怎么样,因为汽车只有 5 个档位?这是否意味着当前档位现在也处于-1?该方法可以返回它更改为的齿轮,这意味着您必须将提供给该方法的参数与返回代码进行比较。那会奏效。另一方面,您可以简单地返回 true 或 false 表示失败,或者返回 false 或 true 表示失败。可以通过估计您是否希望这些方法调用失败或成功来决定使用哪一个。
在我看来,有一种方法可以更好地表达这些返回值的语义,通过给它们一个语义描述。未来与您的对象交互的开发人员会喜欢您,因为您不必为您的方法查找注释或文档:
class GearSystem {
// (...)
public:
enum GearChangeResult
{ GearChangeSuccess, NonExistingGear, MechanicalGearProblem };
GearChangeResult changeGear (int gear);
};
这样,对于任何查看您的代码的程序员来说,返回值的含义就变得非常明显了(考虑一下:if (gears.changeGear(20) == GearSystem::GearChangeSuccess)
- 比上面的示例更清楚这意味着什么)
反模式:失败作为返回码。
我实际上省略了返回值的第四种可能性,因为在我看来它不是任何:当您的程序中出现错误时,例如逻辑错误或需要处理的故障 - 您理论上可以返回一个值指示所以。但是今天,这不再经常(或不应该)这样做,因为为此,有例外。