我有以下简单的情况突然出现在这个地方.大量请求带有如下功能签名的设备:
Err execute( const ICommandContext &context,
const RoutineArguments &arguments,
RoutineResults &results)
Run Code Online (Sandbox Code Playgroud)
基本上有一个请求处理服务器,它将调用它来执行具有这些签名的各种请求类型的函数.在出错的情况下,我们有2条返回路径.
Err输出类型(认为它是相当于int),这是用来通知了毛病就是与系统,不要求做服务器或系统.在处理用户请求之前,始终将其排序在函数顶部.RoutineResults提供setStatus可用于将请求的失败信息返回给客户端的功能.出于这个原因,我们有很多这种类型的代码弹出:
// Failure due to request
Err error = someFunctionCall(clientInput);
if (!error.success()) {
results.setStatus(error); // Inform the client of the error
return SUCCESS; // Inform the system that we are all good
}
Run Code Online (Sandbox Code Playgroud)
我们有一个特定的请求类型,其中包含15参数,这些参数是在系统周围发出的.我们在概念上需要15 if error do套这看起来很浪费.如果我们需要通过并改变我们返回的方式,它也容易出错.我们如何有效地委托setStatus和返回只需要在函数中发生一次的少量代码?
一个c系统可能与宏解决这个问题,是这样的:
#define M_InitTry Err error
#define M_Try(statement) if (!(error = statement).success()) { goto catch_lab; }
#define M_Catch catch_lab: if (!error.successs())
#define M_Return return error
Run Code Online (Sandbox Code Playgroud)
哪个会像这样使用:
Err execute( const ICommandContext &context, ...) {
M_InitTry;
...
M_Try(someFunctionCall(clientInput));
M_Try(someFunctionCall(otherClientInput));
...
M_Catch {
// Other specific actions for dealing with the return.
results.setStatus(error);
error = SUCCESS;
}
M_Return;
}
Run Code Online (Sandbox Code Playgroud)
这很好地清理了代码,但是并不是特别好用goto.如果定义可能被a跳过的变量,则会导致问题goto.
我试图想到更多,C++所以我认为RAII类型的代表可能会有所帮助.就像是:
class DelegateToFunctionEnd {
typedef std::function<void(void)> EndFunction;
public:
DelegateToFunctionEnd(EndFunction endFunction) : callAtEnd(endFunction) { }
~DelegateToFunctionEnd() {
callAtEnd();
}
private:
EndFunction callAtEnd;
};
Run Code Online (Sandbox Code Playgroud)
非常简单,它通过在析构函数中实现操作返回函数来执行操作的委托.您可以像这样使用它:
Err execute( const ICommandContext &context, ...) {
Err error;
DelegateToFunctionEnd del(std::bind(&RoutineResults::setStatus, &results, std::cref(error)));
error = someFunctionCall(clientInput));
if (error) return SUCCESS;
...
}
Run Code Online (Sandbox Code Playgroud)
实例. 这个解决方案似乎没问题,但有几个问题:
if语句来处理退货.这必定是经常出现的问题.是否有一个通用的解决方案提供了这个集合的干净委托并返回类型操作?
我在下面有一些不幸的限制.不要让这些阻止你回答,因为它可能对未来的人有所帮助.
boost,但没有c ++ 11.如果错误状态代码很麻烦,您应该考虑使用异常.也就是说,更改函数的API
std::exception在发生故障时抛出适合的如果你这样做,就不可能"忘记"检查状态代码.如果您选择不处理错误条件,则低级代码抛出的异常会自动向上渗透.如果,您只需要catch一个低级异常
| 归档时间: |
|
| 查看次数: |
220 次 |
| 最近记录: |