依我的謙卑看法,有三種回報情況你應該考慮:
Object property manipulation
第一是操作对象属性。当操作对象时,您所描述的模式经常被使用。非常典型的情况是将其与工厂一起使用。考虑这个假设的创建调用:
// 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的方法一起使用。
Evaluating object properties
第二种可能是当一个方法在对象上评估某些东西。例如,考虑方法car.getCurrentSpeed()
,它可以被解释为对一个对象的消息,请求当前速度并返回。它只会返回值,不太复杂。 :)
Make object do this or that
第三种可能是当一个方法执行操作,在返回某种值时指示调用者的意图实现得如何 - 但是设计这样的方法可能会很困难:
int new_gear = 20;
if (car.gears.changeGear(new_gear)) // does that mean success or fail?
这是在设计方法时可以看到的困难。成功或失败时是否应返回0?如果汽车只有5档,无法设置齿轮,那么-1呢?这是否意味着当前齿轮现在也在-1位置?该方法可以返回更改的齿轮,这意味着您必须将传递给方法的参数与返回代码进行比较。那将起作用。另一方面,您可以只返回失败或真或假或真。其中一个要使用可以通过估计这些方法调用是否更有可能失败或成功来决定。
在我谦虚的观点中,有一种更好地表达这种返回值语义的方法,那就是给它们一个语义描述。未来与你的对象进行交互的开发人员会很感激你,因为他们不必查阅你的方法的注释或文档。
class GearSystem {
// (...)
public:
enum GearChangeResult
{ GearChangeSuccess, NonExistingGear, MechanicalGearProblem };
GearChangeResult changeGear (int gear);
};
这样一来,任何查看你的代码的程序员都会非常明显地知道返回值的含义(考虑:if(gears.changeGear(20) == GearSystem::GearChangeSuccess)
——比上面的例子更清楚地说明了含义)。
Antipattern: Failures as return codes.
第四个可能的返回值我实际上忽略了,因为我认为它并不存在:当你的程序有错误时,例如逻辑错误或需处理的故障 - 你可以理论上返回一个指示这种情况的值。但如今,这并不经常发生(或者不应该),因为有对应的异常处理机制。