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
We take content rights seriously. If you suspect this is your content, claim it here.
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
We take content rights seriously. If you suspect this is your content, claim it here.
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