CodeOath
← All posts
Architecture & Patterns80 min total · 26 parts

ACID, SOLID, and Common Design Patterns: A Software Design Reference

Contents — Part 16 of 26: Structural Patterns: Adapter and Facade
Part 16 of 26 · ~1 min

Structural Patterns: Adapter and Facade

Structural patterns are concerned with how existing objects compose into larger structures without changing their own code.

Adapter converts one interface into another that calling code already expects, letting two otherwise-incompatible pieces of code work together without modifying either one:

// The interface your application code already expects everywhere.
public interface IPaymentProcessor
{
    void Charge(decimal amount);
}

// A third-party library's class, with an interface you don't control.
public class LegacyPaymentGateway
{
    public void MakePayment(int amountInCents) { /* ... */ }
}

// The adapter translates between the two, without modifying either.
public class LegacyPaymentAdapter : IPaymentProcessor
{
    private readonly LegacyPaymentGateway _legacyGateway;
    public LegacyPaymentAdapter(LegacyPaymentGateway legacyGateway) => _legacyGateway = legacyGateway;
    public void Charge(decimal amount) => _legacyGateway.MakePayment((int)(amount * 100));
}

Facade provides one simplified interface over a complex subsystem made of several classes that would otherwise need to be coordinated correctly by every caller:

// Without a facade, every caller needs to know the correct order of
// operations across three separate subsystems.
public class VideoConverter
{
    public void Convert(string filePath, string format)
    {
        var codec = new CodecFactory().GetCodec(format);
        var reader = new VideoFileReader(filePath);
        var bitstream = reader.Read();
        var compressed = codec.Compress(bitstream);
        new FileWriter().Write(compressed, filePath + "." + format);
    }
}

// One simple call is all any calling code needs to know about.
var converter = new VideoConverter();
converter.Convert("movie.avi", "mp4");

The difference between the two is about intent, not mechanism: Adapter's job is compatibility — making an existing interface look like a different one the caller already expects. Facade's job is simplicity — hiding real complexity behind an easier interface, with no compatibility problem to solve.