Menu
Coddy logo textTech

Recap: Logger Factory

Part of the Object Oriented Programming section of Coddy's C journey — lesson 57 of 61.

challenge icon

Challenge

Easy

Let's build a Logger Factory — a system that demonstrates the power of combining the Factory pattern with polymorphism. Your factory will create different logger implementations based on a configuration flag, allowing code to switch between verbose console output and silent "dummy" logging without changing how loggers are used.

You'll organize your code across three files:

  • logger.h: Define a Logger struct that acts as an interface — it should contain a function pointer for log that takes a Logger* and a const char* message. Declare your factory function create_logger that takes an integer flag (1 for console, 0 for dummy) and returns a Logger*. Also declare a free_logger function for cleanup.
  • logger.c: Implement two concrete logger types. The ConsoleLogger embeds Logger as its first member and has a log function that prints messages in the format [LOG] message. The DummyLogger also embeds Logger but its log function does nothing — it simply returns without printing. Create constructor functions for each type that allocate memory and wire up the appropriate log function. Then implement create_logger as a factory that checks the flag and returns the appropriate logger type as a Logger*. Implement free_logger to release memory.
  • main.c: Read an integer (1 or 0) to determine which logger to create. Use your factory to create the appropriate logger, then call its log function with two messages: "Starting application" and "Shutting down". Finally, free the logger.

Your program will receive one input: an integer indicating the logger type (1 for console, 0 for dummy).

Example output when the input is 1:

[LOG] Starting application
[LOG] Shutting down

Example output when the input is 0:

(No output — the dummy logger silently ignores all messages)

The elegance here is that main.c uses the logger identically regardless of which type it receives. The factory decides what to create, and polymorphism ensures the correct behavior executes. This pattern is invaluable in real applications where you might want verbose logging during development but silent operation in production.

Try it yourself

#include <stdio.h>
#include "logger.h"

int main() {
    // Read the logger type flag (1 for console, 0 for dummy)
    int flag;
    scanf("%d", &flag);
    
    // TODO: Use the factory to create the appropriate logger
    
    // TODO: Call the logger's log function with "Starting application"
    
    // TODO: Call the logger's log function with "Shutting down"
    
    // TODO: Free the logger
    
    return 0;
}

All lessons in Object Oriented Programming