Skip to main content
Design Patterns – Complete Beginner to Advanced Guide
CHAPTER 11 Intermediate

Adapter and Facade Patterns

Updated: May 16, 2026
35 min read

# CHAPTER 11

Adapter and Facade Patterns

1. Introduction

We have transitioned from Creational patterns (making objects) to Structural Patterns (assembling objects). In real-world enterprise development, you rarely build an entire system from scratch. You often have to integrate your pristine new code with an ugly, 15-year-old legacy billing system, or a complex third-party API like Stripe or AWS. These external systems have interfaces that are completely incompatible with your application's logic. If you force your clean code to bend to their messy rules, your architecture rots. In this chapter, we will master the Adapter and Facade patterns. We will learn how to build digital translators to bridge incompatible interfaces and construct simple doorways to hide terrifying subsystem complexity.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define the intent of Structural Design Patterns.
  • Understand how the Adapter pattern acts as a real-world translator.
  • Implement an Adapter to safely integrate a third-party API.
  • Understand the Facade pattern's role in simplifying complex systems.
  • Distinguish between an Adapter (changing interfaces) and a Facade (simplifying interfaces).

3. The Adapter Pattern

The Adapter acts exactly like a real-world travel adapter. If you have an American laptop plug and a European wall socket, they are incompatible. The Adapter sits between them, translating the American pins into European holes.
  • The Problem: Your analytics app expects data in XML format. The new stock market API you just purchased only returns JSON. They cannot communicate.
  • The Solution: You create a JsonToXmlAdapter class. Your app talks to the Adapter using standard XML method calls. The Adapter silently translates that request into JSON, fetches the data from the API, translates it back to XML, and returns it. Your app never knows JSON was involved.

4. The Facade Pattern

A Facade is like ordering food at a restaurant. You do not go into the kitchen, chop onions, turn on the stove, and cook the steak. You talk to a Waiter (The Facade). You give a simple command ("I want a steak"), and the Waiter coordinates the massive complexity of the kitchen on your behalf.
  • The Problem: To process a video upload, your code has to manually instantiate the FFmpegEncoder, calculate the BitrateManager, open the AwsS3Connection, and trigger the NotificationService. This is 50 lines of complex, error-prone code scattered throughout your app.
  • The Solution: You create a VideoUploaderFacade class with a single method: uploadVideo(file). The Facade hides the 50 lines of terrifying subsystem logic behind one simple, easy-to-use doorway.

5. Adapter vs. Facade (The Difference)

These patterns look similar but have different intents.
  • Adapter: Makes an existing interface usable. It takes a *complex/incompatible* interface and changes it into the *specific* interface you need. (Translating).
  • Facade: Makes a complex subsystem easy to use. It takes *dozens of complex* classes and provides a *single simplified* interface to control them all. (Simplifying).

6. UML Diagrams

*Adapter Structure*
text
1234567
[ Client ] ---> [ <<Interface>> Target ]
                       ^
                       | (Implements)
                 [ Adapter ]
                       | (Contains & Translates)
                       v
                 [ Incompatible Service ]

*Facade Structure*

text
1234
[ Client ] ---> [ Facade ]
                   |---> [ Subsystem A ]
                   |---> [ Subsystem B ]
                   |---> [ Subsystem C ]

7. Code Example: Adapter (PHP)

Let's safely integrate a third-party Payment Gateway without breaking our app.
php
12345678910111213141516171819202122232425262728293031323334353637383940414243
<?php
// --- 1. Our Application's Standard Interface (The American Plug) ---
interface PaymentGateway {
    public function sendPayment($amount);
}

// --- 2. The Incompatible Third-Party API (The European Socket) ---
class StripeAPI {
    // We cannot change this code. It's a vendor library.
    public function makeStripeCharge($dollars, $cents, $currency) {
        echo "Stripe: Charged $currency $dollars.$cents\n";
    }
}

// --- 3. The Adapter ---
class StripeAdapter implements PaymentGateway {
    private $stripe;

    public function __construct(StripeAPI $stripe) {
        $this->stripe = $stripe; // Wrap the incompatible object
    }

    // Translate our standard interface into the complex vendor logic
    public function sendPayment($amount) {
        $dollars = floor($amount);
        $cents = ($amount - $dollars) * 100;
        
        $this->stripe->makeStripeCharge($dollars, $cents, "USD");
    }
}

// --- 4. Client Code ---
// The client only knows about our standard interface.
function processCart(PaymentGateway $gateway, $total) {
    $gateway->sendPayment($total);
}

// We plug the incompatible API into the Adapter, and give the Adapter to the App.
$vendorAPI = new StripeAPI();
$adapter = new StripeAdapter($vendorAPI);

processCart($adapter, 99.50); // Output: Stripe: Charged USD 99.50
?>

8. Best Practices

  • Anti-Corruption Layer (ACL): In enterprise microservices (Domain-Driven Design), the Adapter pattern is heavily used to create an Anti-Corruption Layer. By forcing all external API communication through Adapters, you prevent the changing, messy logic of third-party vendors from "corrupting" the clean, internal logic of your core application.

9. Common Mistakes

  • The God Facade: If you put *every single feature* of your application behind one massive SystemFacade class, it stops being a helpful doorway and becomes a terrifying God Class that violates the Single Responsibility Principle. Facades should be scoped to specific subsystems (e.g., BillingFacade, SearchFacade).

10. Mini Project: Build an Image Conversion Facade

  1. 1. The Subsystem: Imagine you have three complex classes: FileReader, JpegToPngConverter, and FileWriter.
  1. 2. The Facade: Create a simple ImageConverterFacade class.
  1. 3. The Method: Give it one method: convert($filename, $format).
  1. 4. The Execution: The Facade takes the simple command, opens the FileReader, passes the data to the Converter, and uses the FileWriter to save it. The client code achieves this in exactly one line of code.

11. Practice Exercises

  1. 1. Define the primary intent of the Adapter pattern. Explain the "Travel Adapter" analogy.
  1. 2. Compare the structural intent of the Adapter pattern against the Facade pattern. When would an architect choose to use a Facade?

12. MCQs with Answers

Question 1

An engineering team purchases a legacy XML data-processing library. Their modern application strictly uses JSON. The team cannot alter the legacy library's source code. Which design pattern should they deploy to translate the JSON requests into XML so the systems can communicate?

Question 2

Which architectural pattern is specifically designed to provide a simplified, higher-level interface that hides the terrifying complexity of a massive subsystem containing dozens of interdependent classes?

13. Interview Questions

  • Q: Explain how the Adapter pattern enforces the SOLID Dependency Inversion Principle when dealing with unstable third-party APIs (like Stripe or Twilio).
  • Q: Walk me through the concept of an "Anti-Corruption Layer." How does wrapping external systems in Adapters protect your core business logic from breaking changes implemented by vendors?
  • Q: A junior developer creates a massive class containing thousands of lines of code that interacts with every subsystem in the application, and calls it an "ApplicationFacade." Explain why this violates SOLID principles and how you would refactor it.

14. FAQs

Q: Can an Adapter be a class instead of an object? A: Yes. In languages that support Multiple Inheritance (like C++), you can create a "Class Adapter" that literally inherits from both the target interface and the incompatible class simultaneously. However, "Object Adapters" (using Composition, as shown in the PHP example) are far more common and flexible.

15. Summary

In Chapter 11, we entered the realm of Structural Design. We learned that software rarely exists in a vacuum; it must constantly communicate with ugly, legacy, or complex external systems. We deployed the Adapter pattern to act as a universal translator, allowing incompatible interfaces to work together flawlessly while protecting our core logic from corruption. We utilized the Facade pattern to build simple, elegant doorways that hide the terrifying complexity of massive subsystems. By mastering these patterns, we ensure our applications remain clean, decoupled, and easy to orchestrate.

16. Next Chapter Recommendation

We can translate and simplify existing objects. But how do we dynamically add new behaviors to an object without altering its original code? Proceed to Chapter 12: Decorator and Proxy Patterns.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·