# 5. Design Patterns in C

Design patterns are a powerful tool for software developers to create elegant, reusable, and maintainable code. In this chapter, we will explore several common design patterns in the C programming language and discuss their implementation and use cases.

The first design pattern we will cover is the Singleton pattern. The Singleton pattern ensures that a class can have only one instance, and that it provides a global point of access to that instance. This can be useful in situations where a single instance of a class needs to coordinate actions across the system. To implement the Singleton pattern in C, we can use the following code:

```c
#include <stdio.h>

typedef struct {
    int value;
} Singleton;

Singleton* Singleton_getInstance() {
    static Singleton instance;
    return &instance;
}

int main() {
    Singleton* s1 = Singleton_getInstance();
    Singleton* s2 = Singleton_getInstance();
    printf("s1: %p, s2: %p\n", (void*)s1, (void*)s2); // s1 and s2 should be the same address
    return 0;
}

```

The second design pattern we will cover is the Observer pattern. The Observer pattern is used to define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. In C, we can implement the Observer pattern using function pointers, as shown in the following code:

```c
#include <stdio.h>

typedef struct {
    int value;
    void (*onValueChanged)(int newValue);
} Subject;

void Observer_onValueChanged(int newValue) {
    printf("Observer: new value is %d\n", newValue);
}

int main() {
    Subject subject = { 0, Observer_onValueChanged };
    subject.value = 42;
    subject.onValueChanged(subject.value);
    return 0;
}

```

The third design pattern we will cover is the Factory pattern. The Factory pattern is a creational design pattern that provides an interface for creating objects in a super class, but allows subclasses to alter the type of objects that will be created. In C, we can implement the Factory pattern using function pointers, as shown in the following code:

```c
#include <stdio.h>

typedef struct {
    int value;
} ProductA;

typedef struct {
    float value;
} ProductB;

typedef struct {
    void* (*createProduct)();
} Creator;

void* Creator_createProductA() {
    ProductA* product = (ProductA*)malloc(sizeof(ProductA));
    product->value = 0;
    return product;
}

void* Creator_createProductB() {
    ProductB* product = (ProductB*)malloc(sizeof(ProductB));
    product->value = 0.0f;
    return product;
}

int main() {
    Creator creatorA = { Creator_createProductA };
    Creator creatorB = { Creator_createProductB };

    ProductA* productA = creatorA.createProduct();
    ProductB* productB = creatorB.createProduct();

    printf("ProductA: %d\n", productA);
    }
```
