> For the complete documentation index, see [llms.txt](https://dailyjournal.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dailyjournal.gitbook.io/notes/software-development/software-design-patterns/gof-design-patterns.md).

# GoF Design Patterns

## Creational Pattern

These patterns are designed for class instantiation. They can be either **class-creational** patterns or **object-creational** patterns.

### Factory Method

* The Factory method offers an interface for creating an instance of a class, with its subclasses deciding which class to instantiate.

```csharp
public class CardGame {
    public static CardGame createCardGame(GameType type) {
        if(type == GameType.Poker) {
            return new PokerGame();
        }
        else if(type == GameType.BlackJack) {
            return new BlackJackGame();
        }
        return null;
    }
}
```

### Object Pooling

Object pooling is a software creational design pattern that recycles objects rather than recreating them. It does that by holding selected objects in a pool ready for use when they are requested by an application.&#x20;

This process helps to improve performance by minimizing unnecessary object creation.

> Unity's ObjectPool class can be used, or custom pool managers can be implemented.

### Singleton

* The patterns main objective is to create only one instance of a class and to provide only one global access point to that object.
* With this description, this design pattern perfectly fits in the category of the **Creational Design Patterns**, because at the end, we are **creating** an object, with only a **single** instance.

```csharp
public sealed class NaiveSingleton {
    private static readonly object _lockInstance = new object();
    private static NaiveSingleton _instance = null;

    private NaiveSingleton() { ... }

    public static NaiveSingleton getInstance(){
        lock(_lockInstance){
            if (_instance == null)
                _instance = new NaiveSingleton();
            return _instance;
        }
    }
}
```

* First, Singletons should always be a sealed in order to prevent class inheritance, which could end up with multiple instances which contradicts the purpose of Singleton.
* Second, the constructor must also be private to prevent creating new instances.

#### Disadvantages

* a.k.a. Anti-Pattern, because it can interfere with the unit testing and is inflexible.

## Structural Pattern

These patterns are designed with regard to a class's structure and composition. The main goal pf most of these patterns is to increase the functionality of the class(es) involved, without changing much of its composition.

## Behavioral Pattern

These patterns are designed depending on how one class communicates with others.

### Command

The **command pattern** is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time. This information includes the method name, the object that owns the method, and values for the method parameters.

{% embed url="<https://www.syncfusion.com/blogs/post/command-design-pattern-tutorial-with-csharp-examples.aspx>" %}

{% embed url="<https://www.youtube.com/watch?v=9qA5kw8dcSU>" %}

### Observer

The Observer pattern allows an object (the subject) to notify its dependents (observers) of changes, typically through events or delegates.&#x20;

> In Unity, this pattern is frequently used for event handling, UI updates, and inter-component communication.

### State

**State** is a behavioral design pattern that lets an object alter its behavior when its internal state changes. It appears as if the object changed its class.

> Unity's Animator Controller provides a visual interface for creating state machines for character animations, but you can also implement custom state machines for game logic.

### Strategy

**Strategy** is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.

{% embed url="<https://refactoring.guru/design-patterns>" fullWidth="true" %}
