实验目标
参考《代码中的软件工程》第六章可复用软件设计及lab5.2的源代码,完成实验并写一篇实验报告,总结Callback函数的工作机制以及通过参数进行解耦合的方法,深入理解接口设计中的抽象分层。
Callback函数
什么是Callback函数
回调函数就是一个被作为参数传递的函数。
以 lab5.2 中的代码为例:
// linktable.h
/*
* Search a LinkTableNode from LinkTable
* int Conditon(tLinkTableNode * pNode, void * args);
*/
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args);
这里的 SearchLinkTableNode 函数接收的参数中的 Condition
就是一个函数,这个函数就是回调函数。
Callback函数与普通函数调用的区别
一般一个函数调用另一个函数,被调用的函数是出现在方法体当中。
而回调函数,它是出现在参数列表当中。也就是说当调用的时候,需要从其他地方拿到这个(回调)函数。在宿主函数执行的时候才以参数的形式传入。
在本例中:
// linktable.c
/*
* Search a LinkTableNode from LinkTable
* int Condition(tLinkTableNode * pNode, void * args);
*/
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable,
int Condition(tLinkTableNode * pNode, void * args),
void * args)
{
if(pLinkTable == NULL || Condition == NULL)
{
return NULL;
}
tLinkTableNode * pNode = pLinkTable->pHead;
while(pNode != NULL)
{
if(Condition(pNode, args) == SUCCESS)
{
return pNode;
}
pNode = pNode->pNext;
}
return NULL;
}
函数 SearchLinkTableNode,使用 Condition 函数作为形参。SearchLinkTableNode 函数中不关心 Condition 函数的实现,将 Condition 的功能设计和实现交给用户,实现了用户自定义查询条件。
// menu.c
int SearchCondition(tLinkTableNode * pLinkTableNode, void * args)
{
char * cmd = (char*) args;
tDataNode * pNode = (tDataNode *)pLinkTableNode;
if(strcmp(pNode->cmd, cmd) == 0)
{
return SUCCESS;
}
return FAILURE;
}
/* find a cmd in the linklist and return the datanode pointer */
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
return (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void*)cmd);
}
用户自定义了 SearchCondition 函数的实现,将其作为被回调的函数传递给 SearchLinkTableNode 。
Callback函数的作用
回调其实就是不同程序模块之间的接口和约定,是软件分层设计的基本方式。它实现了调用者和被调用者的解耦,增加了程序设计的灵活性。使得主程序的功能可以有多种实现方式而不需要调用者去关心具体实现细节。使得不同软件模块的开发者的工作进度可以独立出来,不受时空的限制,当需要的时候只需要通过约定好的接口(或者标准)相互契合在一起。
以有多种实现方式而不需要调用者去关心具体实现细节。使得不同软件模块的开发者的工作进度可以独立出来,不受时空的限制,当需要的时候只需要通过约定好的接口(或者标准)相互契合在一起。
另外,在C语言中,回调函数只能使用函数指针来实现,比如C++等语言还可以使用仿函数或匿名函数。
学号:134