Table of contents
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.