cadapter

Design Pattern Adapter in C


Definition:

Adapter is a structural design pattern that allows objects with incompatible interfaces to collaborate.

I have to use incompatible callback function pointers with a difference in the first parameter.

We know objects have key-value pairs, and arrays have index-value pairs. char * vs int.

void object_callback(char *key, void *value) {
    printf("%d: %s\n", index, value);
}

void array_callback(int index, void *value) {
    printf("%d: %s\n", index, value);
}

Use Case

void process_object(void (*callback)(char *key, void *value)) {
    // callback if key-value-based properties
    callback(key, value);

    // callback for array-based properties
    callback((int)key, value); // trying to implement adapter pattern for this
}

I could have used void * but looking for an elegant solution based on Adapter Design Pattern.

My Attempt

#include <stdio.h>

typedef struct Adapter {
    void (*obj)(char *key, void *value);
    void (*arr)(int index, void *value);
} Adapter;

void property_callback(char *key, void *value) {
    printf("%s: %s\n", key, value);
}

void array_callback(int index, void *value) {
    printf("%d: %s\n", index, value);
}

Solution

  • You need to create an adapter function that will bridge the gap between the two different callback interfaces. Here is a simple example of using adapter functions with different callbacks.

    #include <stdio.h>
    
    // Define the original callback functions
    void objectCallback(char *key, void *value) {
        printf("%s: %s\n", key, (char*)value);
    }
    
    void arrayCallback(int index, void *value) {
        printf("%d: %s\n", index, (char*)value);
    }
    
    // Adapter structure to encapsulate the original callbacks
    typedef struct {
        void (*callback)(void* keyOrIndex, void *value);
    } Adapter;
    
    // Adapter function for objectCallback
    void objectAdapter(void* key, void *value) {
        objectCallback((char*)key, value);
    }
    
    // Adapter function for arrayCallback
    void arrayAdapter(void* key, void *value) {
        int idx = (int)(long)key; // Cast void pointer to int
        arrayCallback(idx, value);
    }
    
    int main() {
        // Create an adapter for objectCallback
        Adapter objectAdapterInstance = {objectAdapter};
    
        // Create an adapter for arrayCallback
        Adapter arrayAdapterInstance = {arrayAdapter};
    
        // Demonstrate the use of the adapters
        char* k = "property_key";
        char* v = "property_value";
    
        // Use the object adapter
        objectAdapterInstance.callback(k, v);
    
        // Use the array adapter
        int i = 123;
        arrayAdapterInstance.callback((void*)(long)i, v);
    
        return 0;
    }