Popular design patterns in .NET
/ 1 min read / Ejan Shrestha
Design patterns are essential tools in the arsenal of every .NET developer. They provide proven solutions to recurring design problems, promote code reusability, and improve maintainability. In this blog post, we'll explore three popular design patterns commonly used in .NET development: Singleton, Factory, and Observer.
Singleton Pattern
The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. This pattern is useful when exactly one object is needed to coordinate actions across the system. Here's a basic implementation of the Singleton pattern in C#:
csharpCopy codepublic class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
public void SomeMethod()
{
Console.WriteLine("Singleton method called.");
}
}Usage:
csharpCopy codeSingleton.Instance.SomeMethod();Factory Pattern
The Factory pattern is used to create objects without specifying the exact class of object that will be created. It defines an interface for creating objects, but allows subclasses to alter the type of objects that will be created. Here's a simple example of the Factory pattern:
csharpCopy codepublic interface IProduct
{
void Operation();
}
public class ConcreteProductA : IProduct
{
public void Operation()
{
Console.WriteLine("ConcreteProductA operation");
}
}
public class ConcreteProductB : IProduct
{
public void Operation()
{
Console.WriteLine("ConcreteProductB operation");
}
}
public class ProductFactory
{
public IProduct CreateProduct(string productType)
{
switch (productType)
{
case "A":
return new ConcreteProductA();
case "B":
return new ConcreteProductB();
default:
throw new ArgumentException("Invalid product type");
}
}
}Usage:
csharpCopy codeProductFactory factory = new ProductFactory();
IProduct productA = factory.CreateProduct("A");
IProduct productB = factory.CreateProduct("B");
productA.Operation();
productB.Operation();Observer Pattern
The Observer pattern is a behavioral pattern where an object (the subject) maintains a list of its dependents (observers) and notifies them of any state changes. This pattern is commonly used in event handling systems. Here's a basic example of the Observer pattern:
csharpCopy codepublic interface IObserver
{
void Update(string message);
}
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify(string message);
}
public class ConcreteSubject : ISubject
{
private List<IObserver> observers = new List<IObserver>();
public void Attach(IObserver observer)
{
observers.Add(observer);
}
public void Detach(IObserver observer)
{
observers.Remove(observer);
}
public void Notify(string message)
{
foreach (var observer in observers)
{
observer.Update(message);
}
}
public void DoSomething()
{
// Do something and notify observers
Notify("Something happened");
}
}
public class ConcreteObserver : IObserver
{
public void Update(string message)
{
Console.WriteLine($"Received message: {message}");
}
}Usage:
csharpCopy codeConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observerA = new ConcreteObserver();
ConcreteObserver observerB = new ConcreteObserver();
subject.Attach(observerA);
subject.Attach(observerB);
subject.DoSomething();In conclusion, understanding and applying design patterns in your .NET projects can lead to more maintainable, scalable, and flexible code. The Singleton, Factory, and Observer patterns are just a few examples of the many design patterns available to .NET developers, each with its own use cases and benefits. By incorporating these patterns into your designs, you can write cleaner, more efficient code that is easier to maintain and extend.