可能重复:
How many lines of code should a function/procedure/method have?
Out团队有一个没有结构良好的ansi-c代码的项目。我想使用一些CC技术来整理代码库。
对于C代码,我们有很多指针和很多NULL指针陷阱。因此,有许多片段看起来很相似。就像
if (pointer == NULL)
{
function1();
function2();
}
到处都是。然后有很多函数会以相同的方式相互调用,只有几个变体,比如
function1();
function2a();
function3();
和
function1();
function2b();
function3();
到处都是。
我想将这些块作为单个函数提取,以减少LOC和复制粘贴。但是,除了一些细节之外,这不仅会产生(某种程度上)正交层,而且会产生或多或少相同的功能。更糟糕的是,它会创建能够同时执行许多操作的功能。
那么,什么是好策略?更重要的是,高级别的精益代码,低级别或精益架构的精益功能?哪个原则胜过另一个?分离关注还是干?
我想重构那只野兽,但不知道从哪里开始。
利用下面的示例并将相同的名称放入。让我们假设我们有
morningBath();
drinkCoffee();
if (checkMail())
{
answerMail();
}
并将其放入morningRoutine()。现在我们有了
drinkTea();
morningBath();
if (checkMail())
{
answerMail();
}
并将其称为sundayMorningRoutine()。但后来有重复的代码。或者将morningRoutine(day)展开为
if (day == sunday){
drinkTea();
morningBath();
} else {
morningBath();
drinkCoffee();
}
if (checkMail())
{
answerMail();
}
或者
if (day == sunday){
drink(Tea);
morningBath();
} else {
morningBath();
drink(Coffee);
}
if (checkMail())
{
answerMail();
}
我想知道这是不是很好的风格..也许..谢谢你的提示!
答案 0 :(得分:1)
关于C代码,经常遇到NULL
指针检查是完全正常的,特别是在涉及函数参数时。就个人而言,我更愿意让来电者解决问题,如:
if (p == NULL) {
/* maybe do some cleanup and then: */
return errcode;
}
公共函数,即属于API的函数,应始终检查NULL
指针。指定为static
的函数可以通过IMO删除这些检查。最后,始终有assert()
。编译器标志-NDEBUG
可以抑制这些检查。我在assert()
函数中使用static
而不是if
- 语句和“公共”函数中的测试,这些函数显示调用者实际上并不理解整个API,例如在链接列表中:
void list_print(list **l)
{
assert(l != NULL); /* no valid list passed by reference can ever be NULL */
if (*l == NULL) /* but it can be empty */
return;
/* print list */
}
至于你的第二个问题,我可以看到三个选项:
1)保持原样 - 毕竟,它正在发挥作用。
2)引入新功能:
int function_1_2a_3();
int function_1_2b_3();
3)引入新的参数化函数:
int function_1_2_3(int type);
就个人而言,我更喜欢后一种方法,但这只是一种风格问题。
答案 1 :(得分:1)
对于错误检查,宏可以使您的代码更清晰:
#define CheckNullLogClean(ptr) if(ptr == NULL) { \
status = ERR_NULL_PTR; \
LogError(status); \
goto cleanup; }
int func(int *input) {
status = 0;
CheckNullLogClean(input);
Do_Things();
cleanup:
Release_Resources();
return status;
}
我以前用过的代码库做了类似的事情。并且设置了每个函数,以便在名为status
的标签之后返回一个名为cleanup
的整数(在模块范围的错误代码表中具有值)。如果每个函数调用都检查了它的返回值,我们的日志文件将包含带有文件名和行号的堆栈跟踪(LogError
是一个调用带有__FILE__
和__LINE__
宏的函数的宏)。我们可以在整个项目中使用相同的错误检查宏。
哦,如果你的函数用于类似的目的,也许你迭代的函数指针数组是有意义的。