如何通过多个步骤跟踪状态

how to keep track of status through many steps

本文关键字:跟踪 状态 何通过      更新时间:2023-10-16

我正在处理一些代码,由于它的状态检查,很难重新考虑这些代码。我正试图找出更好的方法来解决这个问题,这样我就可以保持代码的干净/可读性。下面是代码的一个片段:

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循环(无论是什么),但如果一个失败,状态应该保持失败。

有干净的方法吗?或者这可能有一个模式?

EDIT:状态值的枚举

enum status_vals
{
    SUCCESS = 0,
    FAILED = -1,
    FAILED_TIMEOUT = -2,
    FAILED_FATAL = -3,
        etc...
}

模式是使用异常处理。如果不能修改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("%sn", e.what());
}

状态检查的脆弱性是异常的动机之一。通过将错误处理与程序的主流分离,您可以获得更清晰的代码。

作为一种"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);
  }

如果您想尽可能紧密地维护当前的代码结构,并最大限度地减少实现所需功能所需的更改,您可能会添加一个布尔值来跟踪循环中是否有任何调用失败,然后在此基础上设置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();
}