Design Patterns Mastery

Adapter Pattern: Bridging incompatible interfaces

1 Views Updated 5/4/2026

The Adapter Pattern

The Adapter Pattern acts as a "Translator" between two incompatible interfaces. It allows classes to work together that normally couldn't because their method names or data formats don't match. This is the "Universal Plug" of software architecture.

1. Scenario: Legacy Payment Gateway

Imagine your modern system uses a ProcessPayment(decimal amount) method, but you are forced to use an old 1995 library that uses OldCharge(string cents). You don't want to pollute your clean code with 'cents' and 'strings'.

// The clean interface our app expects
public interface IPaymentProcessor 
{
    void ProcessPayment(decimal amount);
}

// THE ADAPTER
public class LegacyPaymentAdapter : IPaymentProcessor 
{
    private readonly LegacyLibrary _legacy;
    
    public void ProcessPayment(decimal amount) 
    {
        // Translate modern decimal to legacy string cents
        var cents = (amount * 100).ToString();
        _legacy.OldCharge(cents); 
    }
}

2. Class vs Object Adapter

  • Object Adapter (Preferred): Uses Composition. The adapter holds an instance of the legacy class.
  • Class Adapter: Uses Multiple Inheritance (not natively supported in C# classes, but simulated using Interfaces). It inherits from both the target and the legacy class.

4. Interview Mastery

Q: "What is the difference between an Adapter and a Proxy?"

Architect Answer: "The difference is **Intent**. An **Adapter** specifically changes the interface to make it compatible with something else (Translation). A **Proxy** provides the *exact same* interface but adds extra behavior like logging, security, or lazy loading (Interception). If you are renaming methods, you are building an Adapter. If you are keeping methods the same but adding logic, you are building a Proxy."

Design Patterns Mastery
1. Introduction to Design Patterns
Introduction to GoF Patterns: Why patterns matter? SOLID Principles: The foundation of all patterns DRY, KISS, and YAGNI (Architectural Philosophy)
2. Creational Patterns
Singleton Pattern: Thread-safety & Captive Dependencies Factory Method: Abstracting complex object creation Abstract Factory: Creating families of related objects Builder Pattern: Constructing complex fluents Prototype Pattern: Cloning high-cost objects
3. Structural Patterns
Adapter Pattern: Bridging incompatible interfaces Bridge Pattern: Decoupling abstraction from implementation Composite Pattern: Managing tree structures & hierarchies Decorator Pattern: Enhancing behavior without inheritance Facade Pattern: Simplifying complex library subsystems Flyweight Pattern: Drastically reducing memory footprint Proxy Pattern: Interception, Lazy-Loading, and Security
4. Behavioral Patterns
Chain of Responsibility: Middleware & Pipeline Architecture Command Pattern: Implementing Undo/Redo & Queueing Interpreter Pattern: Building domain-specific languages Iterator Pattern: Unified traversal of collections Mediator Pattern: Decoupling components with MediatR Memento Pattern: Capturing and restoring object state Observer Pattern: Pub/Sub & Event-driven architecture State Pattern: Managing complex object lifecycles Strategy Pattern: Swappable algorithms at runtime Template Method: Defining skeleton algorithms Visitor Pattern: Separating operations from data structures
5. Modern Enterprise & Cloud Patterns
Repository & Unit of Work (The EF Core Standard) CQRS Pattern (Command Query Responsibility Segregation) Circuit Breaker & Retry Patterns (Resilience with Polly) Dependency Injection Pattern (The Modern King)