Compreensão da função de retorno de chamada e mecanismo de mensagem

[Entendimento do conceito e a diferença entre os dois]

Seja uma função de retorno de chamada ou um mecanismo de mensagem, é a maneira de chamar a função.

Para nós, uma chamada de função é o que achamos que chamamos de um determinado método quando precisamos dele.Esta é a forma mais comum de chamada de função-chamada de método.

Uma chamada de método é chamar um método por meio do nome da classe. A chave para realizar a chamada de método é como encontrar a referência dessa classe. Se for uma classe estática, ou uma classe singleton, ou um método estático, é muito conveniente, caso contrário, precisamos passar a referência dessa classe de várias maneiras.

Quando usamos a chamada de método, atendemos à condição: precisamos chamar uma função B quando uma determinada condição A for atendida e a condição atual A for atendida. (Pode-se dizer também que a condição A de chamar a função B é satisfeita)

Chamadas de método geralmente repetem várias vezes, chamando um método dentro de outro. Por exemplo, quando A é satisfeito, a função B é chamada para obter o resultado C, e imediatamente de acordo com o resultado C, se o resultado C for maior que um determinado valor, a função D é chamada, caso contrário, a função E é chamada. E se a função de chamada de espera e o chamador da função estiverem na mesma classe?

Por exemplo, no método a1 da classe A, o método b1 da classe B será chamado, e a classe A contém a referência da classe B, e a chamada para b1 pode ser concluída em a1 usando a chamada do método. O método a2 na classe A precisa ser chamado quando uma determinada condição for atendida, e essa condição será atendida precisamente no método b1. Então, como chamar o método a2 no método b1?

Se a classe A for uma classe estática ou uma classe singleton, a2 for um método estático e a classe B tiver uma referência à classe A, ela poderá ser chamada diretamente por meio do método. Mas sempre há exceções, não queremos que a classe A seja uma classe estática ou singleton, ou que a2 seja um método estático, ou que a classe B mantenha uma referência à classe A, então precisamos chamar (chamar) b1 em a1 , passando a2 como parâmetro para b1. a2 é a função de retorno de chamada.

Para a classe A, b1 na classe B chama o método de a2, que é um retorno de chamada. Mas para a classe B, o método de chamar a2 em b1 é uma chamada de método normal, que também chama uma função quando uma determinada condição é atendida, mas essa função é uma função de retorno de chamada para a classe A.

Voltar às funções resolve o problema de saber qual função chamar quando uma determinada condição for atendida, mas não quando essa condição for atendida. O que isso significa?

Chamamos o método b1 em a1, e b1 chamará outros métodos para obter o valor de retorno e, em seguida, chamará o método a2 de acordo com o valor de retorno. Em b1, só sabemos chamar a2 quando uma determinada condição for atendida, mas não sei se a condição é satisfeita no processo de ajuste de b1 de a1. É possível satisfazer quando b1 é chamado em outro lugar.

Esta é outra forma de chamada de função, chamando uma função na forma de um retorno de chamada.

Pode-se considerar que a função de retorno de chamada envolve uma camada na chamada do método, que é uma chamada de método disfarçada, e a mensagem é uma camada envolvida com base na função de retorno de chamada, que é uma função de retorno de chamada disfarçada.

Na função de retorno de chamada, o método chamado a2 é passado para o chamador b1 e, na mensagem, a2 precisa ser passado para C, b1 chama o método c1 de C e, em seguida, c1 chama a2. C é o gerenciador da mensagem.Passar a2 para C significa registrar uma mensagem, e b1 chama o método de C c1 significa enviar uma mensagem. Seja registrando ou enviando uma determinada mensagem, ele pode conter uma referência a C e fazer uma chamada de método.

Pode-se ver que o mecanismo de mensagem isola o chamador e o chamado na função de retorno de chamada.O chamador é chamado de remetente da mensagem no mecanismo de mensagem e o chamado é chamado de receptor da mensagem. Apenas esta alteração simples faz a seguinte diferença:

  1. Na mensagem, por estar isolada, o remetente da mensagem não sabe quem recebeu a mensagem, e o destinatário da mensagem não sabe quem enviou a mensagem, e o grau de acoplamento é reduzido. (Tudo bem se você quiser saber, desde que adicione parâmetros extras ao registrar e enviar mensagens.) No retorno de chamada, você pode saber claramente quem ligou e quem foi chamado.
  2. A mensagem possui um gerenciador, e o gerenciador precisa gerenciar o envio e o recebimento de muitas mensagens, ou seja, gerenciar as chamadas de métodos quando diferentes condições são atendidas, e a função callback só é uma chamada de método quando uma determinada condição é atendida.
  3. Uma mensagem pode ter vários remetentes e vários destinatários; em um retorno de chamada, geralmente há apenas um chamador e um chamado. Se uma mensagem tiver apenas um remetente e um destinatário, trata-se, na verdade, de um retorno de chamada. Em mais casos, há um remetente e vários destinatários. O remetente pode anexar diferentes parâmetros ao enviar uma mensagem, e o destinatário da mensagem verifica os parâmetros após receber a mensagem para ver se responde à mensagem, ou seja, verifica se a aceitação é satisfeito, reduza a condição da chamada de função. Portanto, os retornos de chamada têm um controle de parâmetro mais rígido e os parâmetros de mensagem são mais relaxados.
  4. O remetente da mensagem pode decidir quando enviar a mensagem ao gerenciador de mensagens, mas quando enviar a mensagem ao destinatário é determinado pelo gerenciador de mensagens. De um modo geral, o gerenciador de mensagens não a envia imediatamente, mas a envia para o próximo quadro Todos os destinatários da mensagem. Assim, as mensagens são assíncronas. Em um retorno de chamada, o chamador pode chamar imediatamente o chamado, portanto, o retorno de chamada é síncrono.
  5. As mensagens podem cruzar módulos, processos e aplicativos, e os retornos de chamada geralmente são usados ​​em módulos ou módulos de alto nível para chamar módulos de baixo nível. Como o gerenciador de mensagens geralmente é globalmente estático, é fácil ser chamado por diferentes módulos e a mensagem é adequada para comunicação entre vários módulos. Isso está em um aplicativo. Se um aplicativo deseja se comunicar com outro aplicativo, as mensagens também podem ser usadas, porque cada aplicativo é um submódulo do sistema operacional e o sistema operacional tem o equivalente a um gerenciador de mensagens estático global. É perigoso e não é permitido manter diretamente a interface de outro módulo, processo ou aplicativo na forma de retorno de chamada.

[Quando usar mensagens e quando usar callbacks]

  • Considere primeiro o uso de mensagens, principalmente quando se trata de módulos cruzados (essa premissa é saber quando é módulo cruzado)
  • Se for descoberto de acordo com o design da mensagem que uma mensagem possui apenas um remetente e um destinatário, considere o uso de retorno de chamada
  • Se for encontrado de acordo com o design da mensagem, deve ser recebido imediatamente após o envio para manter a sincronização e deve ser usado um callback

[A diferença entre eventos, callbacks e mensagens]

Um evento também é um retorno de chamada generalizado. Um evento geralmente tem apenas um acionador de evento e vários ouvintes de evento; há apenas um chamador e chamado de retorno de chamada; pode haver vários remetentes e destinatários de mensagens.

Os eventos geralmente são acionados por ações ou comportamentos fora do sistema, enquanto as mensagens são geradas por algo ou uma determinada condição dentro do sistema. Quem se inscreve em eventos ou recebe mensagens só precisa saber que algo aconteceu ou uma condição foi atendida.

O sistema aqui se refere a: para o usuário, o aplicativo ou aplicativo é um sistema e a operação de entrada do usuário é um evento. Para um módulo no sistema, as entradas de outros módulos são eventos.

Como geralmente há apenas um acionador de evento, A aciona o evento a, B aciona o evento b após responder ao evento a, C aciona o evento c após responder ao evento b e assim por diante, uma fila de eventos pode ser formada. E as mensagens geralmente não podem formar essa fila de mensagens.

[Diferença entre a função callback e a função hook]

Por exemplo, algo acontece e uma chamada de função é feita, mas você deseja fazer algum processamento após o evento acontecer e determinar se deve fazer uma chamada de função com base no resultado do processamento. Se o código for escrito por você, insira o novo código diretamente antes da chamada da função. Se o código for um sistema ou uma determinada API, você não pode modificar o código aleatoriamente. Você deve inserir uma função no meio. Essa função é uma função de gancho. Pode-se dizer que a função de gancho também é um tipo de função de retorno de chamada. A razão pela qual uma função pode ser inserida é porque as pessoas que escrevem o sistema e a API consideram que alguém deseja fazer um comportamento personalizado.

Então, algo acontece, que tipo de chamada de função é feita posteriormente, uma função de gancho pode ser inserida? Se o que acontece está fortemente associado a uma chamada de função, é difícil de conectar. Obviamente, o mecanismo de mensagem tem baixo acoplamento e é fácil de inserir. Portanto, na maioria das vezes, ao usar a função de gancho, é para interceptar uma determinada mensagem.

【Princípio de profundidade】

Do ponto de vista do computador, como implementar a chamada de função ou como é o processo, você pode ver o seguinte link para uma compreensão mais profunda.

Chamadas de funções C++ para dentro e fora da pilha_George Xiong's blog-CSDN blog_c++ out of the stack function

Alterações na área de pilha durante chamadas de função C++ - (stack frame, esp, ebp)_JMW1407's blog-CSDN blog_c++ stack frame

Princípio do processo de chamada de função C e análise de quadro de pilha de função - stardsd - 博客园 

Guess you like

Origin blog.csdn.net/enternalstar/article/details/126513308