c-sharp
  1. c-sharp-design-patterns-c

C# Design Patterns

C# Design Patterns are reusable solutions to common problems that occur when designing and developing software. Design patterns help to make software more flexible, efficient, and maintainable. In this tutorial, we'll discuss some of the most commonly used design patterns in C#.

Types of Design Patterns

There are three types of design patterns in C#:

  1. Creational Patterns: These patterns provide various object creation mechanisms, which increase flexibility and reuse of existing code.

  2. Structural Patterns: These patterns deal with object composition, making it easier to represent complex data structures.

  3. Behavioral Patterns: These patterns focus on communication between objects, providing flexibility to modify behaviors and communication patterns in your code.

Examples

There are many different design patterns in C#, but we'll focus on a few of the most commonly used ones.

Singleton Pattern

The Singleton pattern ensures that only one instance of a class is created and provides global access to that instance.

public class Singleton {
   private static Singleton instance;
   private Singleton() {}

   public static Singleton GetInstance() {
      if (instance == null) {
         instance = new Singleton();
      }
      return instance;
   }
}

Factory Pattern

The Factory pattern provides a way to create objects without specifying the exact class of object that will be created.

public interface IShape {
   void Draw();
}

public class Circle : IShape {
   public void Draw() {
      Console.WriteLine("Drawing a circle");
   }
}

public class Square : IShape {
   public void Draw() {
      Console.WriteLine("Drawing a square");
   }
}

public class ShapeFactory {
   public static IShape GetShape(string shapeType) {
      switch (shapeType.ToLower()) {
         case "circle":
            return new Circle();
         case "square":
            return new Square();
         default:
            throw new ArgumentException("Invalid shape type");
      }
   }
}

Observer Pattern

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

public interface IObserver {
   void Update(int temperature);
}

public interface ISubject {
   void RegisterObserver(IObserver observer);
   void RemoveObserver(IObserver observer);
   void NotifyObservers();
}

public class WeatherData : ISubject {
   private List<IObserver> observers = new List<IObserver>();
   private int temperature;

   public void RegisterObserver(IObserver observer) {
      observers.Add(observer);
   }

   public void RemoveObserver(IObserver observer) {
      observers.Remove(observer);
   }

   public void NotifyObservers() {
      foreach (IObserver observer in observers) {
         observer.Update(temperature);
      }
   }

   public void SetTemperature(int temperature) {
      this.temperature = temperature;
      NotifyObservers();
   }
}

public class Display : IObserver {
   public void Update(int temperature) {
      Console.WriteLine("Temperature updated to " + temperature);
   }
}

Explanation

In the examples above, we defined three different design patterns: Singleton, Factory, and Observer.

The Singleton pattern ensures that only one instance of a class is created and provides global access to that instance. We created a Singleton class with a private constructor and a GetInstance method that returns the single instance of the class.

The Factory pattern provides a way to create objects without specifying the exact class of object that will be created. We created a Factory class that returns an object of type IShape. The implementation of this interface can vary, allowing for flexibility in the creation of objects.

The Observer pattern provides a way to define a one-to-many dependency between objects, so that when one object changes state, all its dependents are notified and updated automatically. We created two interfaces: IObserver and ISubject. We also created two classes: WeatherData (which is the subject) and Display (which is an observer). When the temperature changes in WeatherData, it notifies all its observers by calling the Update method.

Use

Design patterns are useful for providing solutions to common problems that occur when designing and developing software. By using design patterns, you can increase flexibility, efficiency, and maintainability in your code.

Important Points

  • Design patterns are reusable solutions to common problems that occur when designing and developing software.
  • There are three types of design patterns: Creational, Structural, and Behavioral.
  • Each type contains a variety of patterns that can be used to solve specific problems in your code.
  • Design patterns help to make software more flexible, efficient, and maintainable.

Summary

In this tutorial, we discussed some of the most commonly used design patterns in C#. We covered the types of design patterns, examples of three different patterns (Singleton, Factory, and Observer), the explanation, use, important points, and summary of C# design patterns. With this knowledge, you can now use design patterns in your C# code to provide solutions to common problems and increase flexibility, efficiency, and maintainability in your code.

Published on: