0% found this document useful (0 votes)
3 views

Complete_CSharp_Design_Patterns

The document outlines six design patterns in C#: Singleton, Factory Method, Abstract Factory, Adapter, Observer, and Strategy. Each pattern includes its intent, use cases, code examples, pros, and cons, along with a comparison table summarizing their types and purposes. These patterns are essential for creating flexible and maintainable software architectures.

Uploaded by

akshay
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Complete_CSharp_Design_Patterns

The document outlines six design patterns in C#: Singleton, Factory Method, Abstract Factory, Adapter, Observer, and Strategy. Each pattern includes its intent, use cases, code examples, pros, and cons, along with a comparison table summarizing their types and purposes. These patterns are essential for creating flexible and maintainable software architectures.

Uploaded by

akshay
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Design Patterns in C#

1. Singleton Pattern

---------------------

Intent:

Ensure a class has only one instance and provide a global point of access to it.

Use Case:

Logger, Config Manager, Thread Pools

Code Example:

public sealed class Singleton {

private static Singleton _instance = null;

private static readonly object _lock = new object();

private Singleton() { }

public static Singleton Instance {

get {

lock (_lock) {

if (_instance == null)

_instance = new Singleton();

return _instance;

public void DoWork() {

Console.WriteLine("Singleton doing work");

}
Pros:

- Saves memory with lazy initialization

- Globally accessible instance

Cons:

- Difficult to unit test/mock

- Hidden dependencies

------------------------------------------------------------

2. Factory Method Pattern

--------------------------

Intent:

Define an interface for creating an object but let subclasses decide which class to instantiate.

Use Case:

Creating objects like Shapes, Buttons, Notifications

Code Example:

abstract class Product {

public abstract void Operation();

class ConcreteProductA : Product {

public override void Operation() => Console.WriteLine("Product A");

class ConcreteProductB : Product {

public override void Operation() => Console.WriteLine("Product B");

abstract class Creator {

public abstract Product FactoryMethod();


}

class ConcreteCreatorA : Creator {

public override Product FactoryMethod() => new ConcreteProductA();

class ConcreteCreatorB : Creator {

public override Product FactoryMethod() => new ConcreteProductB();

Pros:

- Decouples object creation from usage

- Easier to introduce new product types

Cons:

- More classes and code to manage

------------------------------------------------------------

3. Abstract Factory Pattern

-----------------------------

Intent:

Provide an interface for creating families of related objects without specifying their concrete classes.

Use Case:

Cross-platform UI components, Themes

Code Example:

interface IButton {

void Paint();

class WinButton : IButton {


public void Paint() => Console.WriteLine("Windows Button");

class MacButton : IButton {

public void Paint() => Console.WriteLine("Mac Button");

interface IGUIFactory {

IButton CreateButton();

class WinFactory : IGUIFactory {

public IButton CreateButton() => new WinButton();

class MacFactory : IGUIFactory {

public IButton CreateButton() => new MacButton();

Pros:

- Supports consistency among products

- Easy to switch families

Cons:

- Difficult to add new product types

------------------------------------------------------------

4. Adapter Pattern

-------------------

Intent:

Convert the interface of a class into another interface the client expects.
Use Case:

Integration with legacy or external APIs

Code Example:

interface ITarget {

void Request();

class Adaptee {

public void SpecificRequest() => Console.WriteLine("SpecificRequest");

class Adapter : ITarget {

private Adaptee _adaptee = new Adaptee();

public void Request() => _adaptee.SpecificRequest();

Pros:

- Reuse existing code

- Improve compatibility

Cons:

- Added layer increases complexity

------------------------------------------------------------

5. Observer Pattern

--------------------

Intent:

One-to-many dependency between objects so when one object changes, others are notified.

Use Case:

Event listeners, Pub/Sub systems


Code Example:

interface IObserver {

void Update(string message);

interface ISubject {

void Attach(IObserver observer);

void Detach(IObserver observer);

void Notify();

class ConcreteSubject : ISubject {

private List<IObserver> observers = new();

private string message;

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(message);

public void CreateMessage(string msg) {

message = msg;

Notify();

class ConcreteObserver : IObserver {

private string _name;

public ConcreteObserver(string name) => _name = name;

public void Update(string message) => Console.WriteLine($"{_name} received: {message}");


}

Pros:

- Loose coupling

- Dynamic subscriber list

Cons:

- Possible memory leaks

- Hard to debug

------------------------------------------------------------

6. Strategy Pattern

--------------------

Intent:

Define a family of algorithms, encapsulate each one, and make them interchangeable.

Use Case:

Payment options, compression algorithms

Code Example:

interface IStrategy {

void Execute();

class StrategyA : IStrategy {

public void Execute() => Console.WriteLine("Executing Strategy A");

class StrategyB : IStrategy {

public void Execute() => Console.WriteLine("Executing Strategy B");

}
class Context {

private IStrategy _strategy;

public Context(IStrategy strategy) => _strategy = strategy;

public void SetStrategy(IStrategy strategy) => _strategy = strategy;

public void ExecuteStrategy() => _strategy.Execute();

Pros:

- Easy to switch algorithms

- Eliminates conditionals

Cons:

- More code structure

- Overhead of additional classes

------------------------------------------------------------

Design Pattern Comparison Table

-------------------------------

| Pattern | Type | Intent | Use Case |

|------------------|-------------|---------------------------------------|-------------------------|

| Singleton | Creational | Ensure a single instance | Logger, Config Manager |

| Factory Method | Creational | Delegate instantiation to subclass | Button, Shape Factory |

| Abstract Factory | Creational | Create related object families | Cross-platform UI |

| Adapter | Structural | Match incompatible interfaces | Legacy integration |

| Observer | Behavioral | Notify multiple objects of change | Event systems |

| Strategy | Behavioral | Select algorithm at runtime | Payment systems |

You might also like