CODESAMPLE
Proxy - C
The Proxy pattern provides a surrogate or placeholder for another object to control access to it. This is useful for scenarios like remote access, security checks, or lazy initialization. Here, we proxy a File object with a FileProxy that handles file opening and reads. The FileProxy checks if the file is already open; if not, it opens it and stores the File pointer for subsequent use. This avoids repeatedly opening the file, improving performance. The implementation uses C’s pointer-based approach to manage the underlying File object and demonstrates encapsulation through function pointers. It’s a common pattern in C, leveraging its ability to work directly with memory addresses.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Interface for the real object (File)
typedef struct File {
char *filename;
int data;
int isOpen;
} File;
File *file_create(const char *filename) {
File *f = (File *)malloc(sizeof(File));
if (f) {
f->filename = strdup(filename);
f->data = 0;
f->isOpen = 0;
}
return f;
}
void file_open(File *file) {
printf("Opening file: %s\n", file->filename);
file->isOpen = 1;
// Simulate reading data from the file
file->data = 42;
}
int file_read(File *file) {
if (file->isOpen) {
printf("Reading from file: %s\n", file->filename);
return file->data;
} else {
printf("File is not open.\n");
return -1;
}
}
void file_close(File *file) {
printf("Closing file: %s\n", file->filename);
file->isOpen = 0;
}
void file_destroy(File *file) {
if (file) {
free(file->filename);
free(file);
}
}
// Proxy interface
typedef struct FileProxy {
File *realFile;
char *filename;
} FileProxy;
FileProxy *file_proxy_create(const char *filename) {
FileProxy *proxy = (FileProxy *)malloc(sizeof(FileProxy));
if (proxy) {
proxy->realFile = NULL;
proxy->filename = strdup(filename);
}
return proxy;
}
void file_proxy_open(FileProxy *proxy) {
if (proxy->realFile == NULL) {
proxy->realFile = file_create(proxy->filename);
file_open(proxy->realFile);
} else {
printf("File already open.\n");
}
}
int file_proxy_read(FileProxy *proxy) {
if (proxy->realFile == NULL) {
printf("File not opened yet.\n");
return -1;
}
return file_read(proxy->realFile);
}
void file_proxy_close(FileProxy *proxy) {
if (proxy->realFile != NULL) {
file_close(proxy->realFile);
file_destroy(proxy->realFile);
proxy->realFile = NULL;
}
}
void file_proxy_destroy(FileProxy *proxy) {
if (proxy) {
free(proxy->filename);
free(proxy);
}
}
int main() {
FileProxy *proxy = file_proxy_create("my_file.txt");
file_proxy_read(proxy); // File not opened yet.
file_proxy_open(proxy);
int data = file_proxy_read(proxy);
printf("Data read: %d\n", data);
file_proxy_open(proxy); // File already open.
file_proxy_close(proxy);
file_proxy_read(proxy); // File not opened yet.
file_proxy_destroy(proxy);
return 0;
}