我正在处理一些因为状态检查而难以重新考虑的代码。我试图找出更好的解决方法,以便我可以保持我的代码清洁/可读。以下是代码的代码:
int status = FAILED;
status = fn_action_one();
if (status != SUCCESS)
{
printf("ERROR: returned from fn_action_one()\n");
}
else
{
status = fn_action_two();
}
if (status != SUCCESS)
{
printf("ERROR: returned from fn_action_two()\n");
}
else
{
status = fn_action_three();
}
对我来说问题是我现在想要重构这段代码并循环遍历它的一部分:
int status = FAILED;
status = fn_action_one();
if (status != SUCCESS)
{
printf("ERROR: returned from fn_action_one()\n");
}
else
{
// This task is now required to be done multiple times...
for (int i = 0; i < numLoop; i++)
{
status = fn_action_two(i); // Keeping track of the status here is now an issue
}
}
// If any of the looped action_two's had a fail this check should fail
if (status != SUCCESS)
{
printf("ERROR: returned from fn_action_two()\n");
}
else
{
status = fn_action_three();
}
这现在变得很困难,因为在循环时我想要在所有numLoop
次循环(无论是什么),但如果一个失败,状态应该保持失败。
有干净的方法吗?或者可能有这种模式?
编辑:枚举状态值
enum status_vals
{
SUCCESS = 0,
FAILED = -1,
FAILED_TIMEOUT = -2,
FAILED_FATAL = -3,
etc...
}
答案 0 :(得分:3)
'模式'是使用异常处理。如果你不能修改fn_action_xxx()然后写包装器
void my_action_one()
{
int status = fn_action_one();
if (status != SUCCESS)
throw std::runtime_error("ERROR: returned from fn_action_one()");
}
...
try
{
my_action_one();
for (int i = 0; i < numLoop; i++)
{
my_action_two(i);
}
my_action_three();
}
catch (const std::exception& e)
{
printf("%s\n", e.what());
}
状态检查的脆弱性是异常的动机之一。通过将错误处理与程序的主流分离,您可以获得更清晰的代码。
答案 1 :(得分:1)
作为有点“C”方法,我会使用宏和goto的组合。
#define CHECK(expr) \
{ \
if( SUCCESS != (status = expr) ){ \
printf("ERROR: returned from " #EXPR "\n"); \
goto End
} \
}
int status = FAILED;
CHECK(fn_action_one());
End:
return status;
在循环内我会做
if (status != SUCCESS)
{
status = fn_action_two(i);
}
答案 2 :(得分:1)
如果你想尽可能地保持当前的代码结构,并尽量减少实现所需功能所需的更改,你可以通过添加一个布尔值来跟踪循环中的任何调用是否失败,然后根据以下内容设置status
:
int status = FAILED;
status = fn_action_one();
if (status != SUCCESS)
{
printf("ERROR: returned from fn_action_one()\n");
}
else
{
bool failed = false;
// This task is now required to be done multiple times...
for (int i = 0; i < numLoop; i++)
failed |= (fn_action_two(i) == FAILED);
}
if (failed)
status = FAILED;
// If any of the looped action_two's had a fail this check should fail
if (status != SUCCESS)
{
printf("ERROR: returned from fn_action_two()\n");
}
else
{
status = fn_action_three();
}