如何构建具有许多故障点的代码? [英] How to structure code with many failure points?
问题描述
我有一段代码可能会在很多时候失败.每增加一个动作(也可能失败),可读性就会变差.有没有更好的方法来构造它?有没有针对此的设计模式?
I have a piece of code that can fail at many points. With each additional action (that can also fail), the readability worsens. Is there a better way to structure this? Is there a design pattern for this?
int32_t InitializeMyThingy(void) {
int32_t retcode;
retcode = DoA();
if (retcode != 0) return retcode;
retcode = DoB();
if (retcode != 0) return retcode;
retcode = DoC();
if (retcode != 0) return retcode;
retcode = DoD();
return retcode;
}
或者(更易读?):
int32_t InitializeMyThingy(void) {
int32_t retcode;
retcode = DoA();
if (0 == retcode) {
retcode = DoB();
if (0 == retcode) {
retcode = DoC();
if (0 == retcode) {
retcode = DoD();
}
}
}
return retcode;
}
推荐答案
在 C 中,带有 goto
的 SESE(单入口,单出口)模式通常是合适的:
In C, a SESE (single entry, single exit) pattern with goto
is usually appropriate:
int32_t InitializeMyThingy(void) {
int32_t retcode;
retcode = DoA();
if (retcode != 0) goto exit;
retcode = DoB();
if (retcode != 0) goto exit;
retcode = DoC();
if (retcode != 0) goto exit;
retcode = DoD();
exit:
return retcode;
}
就其本身而言,这与在每次检查后具有 return
语句的第一个示例没有任何不同.但是一旦您的代码开始分配资源,goto
方法就会更加简洁:
By itself, this isn't any different from your first example that has return
statements after each check. But once you your code starts allocating resources, the goto
approach is much cleaner:
int32_t InitializeMyThingy(void) {
int32_t retcode = E_FAIL;
A* a = NULL;
B* b = NULL;
C* c = NULL;
a = AllocateA();
if (a == NULL) goto exit;
b = AllocateB(a);
if (b == NULL) goto exit;
c = AllocateC(b);
if (c == NULL) goto exit;
retcode = DoSomething(c);
exit:
free(c);
free(b);
free(a);
return retcode;
}
现在您不必担心在每个出口点确定要清理的内容.
and now you don't have to worry about figuring out what to clean up at every individual exit point.
尽管许多反对者对 goto
持反对意见,但如果使用得当,它是 C 中最明智的错误处理形式.
Despite what many naysayers say about goto
, when used properly, it is the sanest form of error-handling in C.
关于添加额外动作的可读性,我认为用空格分隔动作有很大帮助.或者,如果您真的想要紧凑性,您可以考虑执行内联操作和错误检查:
Regarding readability from adding additional actions, I think separating actions with whitespace helps a lot. Or, if you really want compactness, you could consider doing the action and the error check inline:
if ((retcode = DoA()) != 0) goto exit;
这篇关于如何构建具有许多故障点的代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!