Uso de devoluciones de llamada en arquitectura en capas

Desde el modelo OSI de red hasta el Sistema Operativo, cualquier proyecto de la vida diaria se basa en una arquitectura en capas. ¿Alguna vez pensaste cómo se crea la abstracción entre las capas superiores y las capas inferiores?

Se trata de devoluciones de llamada . Por lo tanto, en general, las capas superiores se crean para hacer las cosas más simples y fáciles de usar (como los SDK) y las capas inferiores son las capas reales que interactúan con la red (para un proyecto basado en redes) o llamadas a nivel del sistema (para proyectos basados ​​en SO). Entonces, podemos llamar directamente a una función, definida (y también declarada) en la capa inferior, desde un archivo fuente de la capa superior y pasar los datos a través de los argumentos de la función. Pero no podemos simplemente llamar a una función de la capa superior desde las capas inferiores, ya que eso creará una dependencia circular. Entonces, aquí las devoluciones de llamadas entran en escena.

La devolución de llamada es la forma de pasar una función a través de su referencia como argumento de otra función y llamarla más tarde por la referencia.

Digamos que upperlayer.c y lowerlayer.c son archivos fuente de la capa superior y la capa inferior respectivamente. lowerlayer.h es el archivo de encabezado de lowerlayer.c . En upperlayer.c , primero se pasa la referencia de función de apply_observer() a lowerlayer.c como un argumento de register_callback() . Esto se llama registrar la devolución de llamada en la capa inferior. Ahora, la capa inferior conoce la referencia de función de notificar_observador() . La función register_callback() simplemente almacena la referencia de la función en un puntero de función global g_notify_ob, para que cualquier función del archivo pueda llamar a notificar_observador() . Ahora, cada vez que la capa inferior necesita pasar datos a la capa superior (o necesita enviar una notificación), simplemente llama a notificar_observador() llamando a g_notificar_ob() .

A continuación se muestra upperlayer.c

#include <stdio.h>
#include "lowerlayer.h"
  
void notify_observer()
{
    printf("Function called by callback\n");
}
  
int main()
{
    // Calling register_callback function and 
    // passing address of notify_observer as argument
    register_callback(notify_observer);  
    lowerlevelfunction();
}

Esta es la capa inferior.h. La línea resaltada es solo para indicar el prototipo de la función de devolución de llamada que en realidad se pasará como referencia. La plantilla básica del prototipo es como,

typedef <Function return type> (*<Name of the function pointer type>)
                      (<Type of Function arguments separated by comma>)
// Below is the prototype of the function 
// that will be actually passed by reference 
typedef void (*notify_ob)(void);
  
void register_callback(notify_ob);
  
void lowerlevelfunction();

Ahora esto es lowerlayer.c

#include "lowerlayer.h"
#define NULL 0
  
notify_ob g_notify_ob;
  
// Callback function
void lowerlevelfunction()
{ 
    // Calling back to notify_observer
    g_notify_ob(); 
}
  
// Callback registration
void register_callback(notify_ob fun)
{
    g_notify_ob = fun;
}

Si compilamos y ejecutamos estos archivos como estos, la salida será así.

$gcc -c upperlayer.c
$gcc -c lowerlayer.c
$gcc -o exe upperlayer.o lowerlayer.o
$./exe

Output: Function called by callback 

Publicación traducida automáticamente

Artículo escrito por samanwayd y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *