工程化编程实战callback接口学习笔记

1.代码debug

//输入"help"程序都返回为"This is a wrong cm";

//输入"version""quit"程序返回正常;

工程化编程实战callback接口学习笔记_第1张图片

//设置断点,检查输入"quit"时指针p为空指针的原因;

工程化编程实战callback接口学习笔记_第2张图片

//输入"quit"程序后,调用FIndCmd获取p值,而FindCmd又调用SearchLinkTableNode;

//SearchLinkTableNode的逻辑中,while内使用回调函数Condition判断用户指令是否正确;

//while循环判断存在异常,当pNode=pLinkTable->tail时,程序直接return NULL;

工程化编程实战callback接口学习笔记_第3张图片

//根据menu.c中的InitMenuData,我们可以知道"quit"指令是pLinkTable的第三个节点;

//结合上述代码流程,这就解释了为什么输入"version""help"都没有问题,而"quit"指令异常;

 工程化编程实战callback接口学习笔记_第4张图片

//修改代码后重新测试。 

工程化编程实战callback接口学习笔记_第5张图片

2.callback接口运行机制、callback设计方案

什么是callback?

把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调。

如果代码立即被执行就称为同步回调,如果在之后晚点的某个时间再执行,则称之为异步回调。

举例定义:函数A()作为函数B(int (* A))的函数指针参数,在函数B中会调用函数A的方法,函数A是回调函数。

 

为什么需要callback?

使用callback可以的好处和作用就是解耦,结合callback的实际开发场景,我们可以更好的理解它。

参考博文:https://www.cnblogs.com/arsh/p/11283806.html

A(int m, int n, bool * f(m,n))

1. 既然是函数的参数,就具备了扩展性和代码重用的作用,因为形参不变,实参是可变的。所以调用时,可以A(x,y,B),也可以A(x,y,C),这里B和C都是回调函数,有点像虚函数。(B和C可以实现不同的功能,或以不同的方式实现)

----场景:代码重用。A(x, y, isGreater), A(x, y , isSmaller)

2. 在定义A()时,甚至不需要知道实际的被调函数的名字,只要知道这个接口的格式,即参数,返回值,实现功能。所以甚至在确定被调函数如何实现之前,只要约定好接口和功能,就可以进行A()的定义工作。(实现相同的功能)

----场景:框架编程,并行工作。业务流程步骤编排(不管具体实现)。

A(bool * f())

3. 甚至被调函数f()到底实现什么功能,也是可以不定义的。只是在A里面规定好条件触发,将具体做什么的决定权交给用户。

 ----场景:事件,通知。

我猜OnTimer()应当就是一个回调函数,开放给用户自定义动作。整个定时器的机制已经是预定义好的。

main函数其实也是。都是事件机制。

4. 结合多线程异步使用。

----场景:工作继续进行,主函数先结束。

void  A(url, call)
{
      开启url线程,传入call
      函数本身返回.
}

 5.结合延迟函数。

void  A(call)
{
      setTimeout(call, 10000)
      函数本身返回.
}
View Code

 

 

callback运行机制以及实例分析。

 //自定义的回调函数,用于判断用户输入的指令是否正确;

int SearchCondition(tLinkTableNode * pLinkTableNode)
{
    tDataNode * pNode = (tDataNode *)pLinkTableNode;
    if(strcmp(pNode->cmd, cmd) == 0)
    {
        return  SUCCESS;  
    }
    return FAILURE;           
}

 //定义函数SearchLinkTableNode,带有callback接口;

tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode))
{
    if(pLinkTable == NULL || Conditon == NULL)
    {
        return NULL;
    }
    tLinkTableNode * pNode = pLinkTable->pHead;
    while(pNode != NULL)
    {    
        if(Conditon(pNode) == SUCCESS)
        {
            return pNode;                    
        }
        pNode = pNode->pNext;
    }
    return NULL;
}

//将SearchCondition作为函数指针参数提供给函数SearchLinkTableNode;

//函数SearchLinkTableNode执行Condition(pNode)时会调用函数SearchCondition。

tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
    return  (tDataNode*)SearchLinkTableNode(head,SearchCondition);
}

 

callback接口设计方法。

callback无参数接口设计

int A(){
  return 0;
}

int B(int (*Callback)()){
    return Callback();
}
int main(){ 
  B(A);
  return 0;
}

callback多参数接口设计

int A(int a, int b){
    return a+b;
}

int B(int a, int b, int (*Callback)(int, int)){
    return Callback(a, b);
}

int main(){
    B(1,2,A);
    return 0;    
}

 

你可能感兴趣的:(工程化编程实战callback接口学习笔记)