Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Design Patterns in C#

Introduction to Design Patterns

Design patterns are typical solutions to common problems in software design. Each pattern is like a blueprint that you can customize to solve a particular design problem in your code. These patterns are categorized into three types: Creational, Structural, and Behavioral.

Creational Patterns

Creational patterns deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by controlling the creation process.

1. Singleton Pattern

The Singleton pattern ensures that a class has only one instance and provides a global point of access to it.

Example:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

Structural Patterns

Structural patterns explain how to assemble objects and classes into larger structures while keeping these structures flexible and efficient.

2. Adapter Pattern

The Adapter pattern allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.

Example:

public interface ITarget
{
    void Request();
}

public class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Called SpecificRequest()");
    }
}

public class Adapter : ITarget
{
    private readonly Adaptee _adaptee;

    public Adapter(Adaptee adaptee)
    {
        _adaptee = adaptee;
    }

    public void Request()
    {
        _adaptee.SpecificRequest();
    }
}

Behavioral Patterns

Behavioral patterns are concerned with algorithms and the assignment of responsibilities between objects. They help in defining communication between objects and how the flow is controlled in a complex program.

3. Observer Pattern

The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Example:

using System;
using System.Collections.Generic;

public interface IObserver
{
    void Update();
}

public class ConcreteObserver : IObserver
{
    private string _name;

    public ConcreteObserver(string name)
    {
        _name = name;
    }

    public void Update()
    {
        Console.WriteLine($"{_name} has received an update!");
    }
}

public class Subject
{
    private List _observers = new List();

    public void Attach(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void Detach(IObserver observer)
    {
        _observers.Remove(observer);
    }

    public void Notify()
    {
        foreach (var observer in _observers)
        {
            observer.Update();
        }
    }
}

Conclusion

Design patterns are essential tools for developers that provide solutions to common problems and improve the design of software applications. By understanding and applying these patterns, developers can create more robust, reusable, and maintainable code.