Common C# design patterns and when to use them

Common C# design patterns and when to use them

·

3 min read

Design patterns are a set of reusable solutions to common software design problems. They are a way to structure and organize code in a way that is easy to understand, maintain, and scale. In this article, we will be focusing on design patterns in the C# programming language.

There are three main categories of design patterns: creational, structural, and behavioral. Creational patterns deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. Structural patterns focus on object composition, creating relationships between objects to form larger structures. Behavioral patterns focus on communication between objects, what goes on between objects, and how they operate together.

Singleton Pattern

One of the most popular creational patterns in C# is the Singleton pattern. This pattern ensures that a class has only one instance and provides a global access point to it. The Singleton pattern is often used when we need to have only one instance of a class for the entire application, such as for a database connection or configuration settings.

In this example, the Singleton class has a private constructor, which means that it cannot be instantiated from outside the class. The Instance property is a static property that returns the single instance of the Singleton class. The lock statement is used to ensure thread safety, so that multiple threads cannot access the Instance property at the same time and create multiple instances of the Singleton class. To use the Singleton class, you would access the Instance property like this:

This will ensure that you are always getting the same instance of the Singleton class, no matter how many times you access the Instance property.

Adapter Pattern

A common structural pattern in C# is the Adapter pattern. This pattern allows two incompatible interfaces to work together by converting the interface of one class into another. The Adapter pattern is often used when we want to use an existing class in a system but its interface is not compatible with the rest of the classes.

In this example, the Adaptee class contains an existing method GetSpecificRequest() that needs to be adapted to the ITarget interface. The Adapter class adapts the Adaptee to the ITarget interface by implementing the GetRequest() method and calling the GetSpecificRequest() method of the Adaptee. The Client class works with the ITarget interface and can use the Adapter to make a request without knowing about the adaptee's specific implementation.

Observer Pattern

An example of a behavioral pattern in C# is the Observer pattern. This pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically. The Observer pattern is often used in event-driven systems, such as user interfaces, where we want to be notified of certain events or actions.

To use this code, you would first create a Stock object and several Investor objects. Then, you would register the investors as observers of the stock by calling the RegisterObserver() method on the stock and passing in the investor as an argument. When the stock price changes, the SetPrice() method is called on the stock, which in turn calls the NotifyObservers() method to update all registered investors.

In conclusion, design patterns are an important concept in software development, as they provide a common language for developers to communicate and a set of proven solutions to common design problems. Understanding and using design patterns can help you write better, more maintainable, and more scalable code. See you in the next one.