Introduction

Welcome! In this lesson, we'll dissect two main software design patterns: the Facade and Adapter patterns. We aim to unravel how these patterns ensure backward compatibility while adding new features. Backward compatibility means that new updates don't break existing systems, allowing for new functionalities without affecting the current code. Think of the Facade and Adapter patterns as cassette-shaped tape adapters for CD players, bridging the new and the old.

Overview of Design Patterns

Design patterns are recognized solutions to frequent problems in software design and are time-tested methods resulting from the craftsmanship of seasoned developers. Among many design patterns, we're focusing on the Facade and Adapter patterns today. The Facade pattern provides a simplified interface to a complex subsystem, whereas the Adapter pattern enables classes with incompatible interfaces to work together. Let's delve deeper to unravel their use cases.

Peeking into the Facade Pattern

The Facade pattern simplifies complex processes by providing a higher-level interface. Consider an online shopping application. When a user places an order, it triggers many operations. By using the Facade pattern, we can create an OrderFacade class to simplify these operations:

// Define subsystems
class Order {
    public void create() {
        System.out.println("Order Created");
    }
}

class Product {
    public void checkAvailability() {
        System.out.println("Product Availability Checked");
    }
}

class Payment {
    public void processPayment() {
        System.out.println("Payment Processed");
    }
}

class Delivery {
    public void arrangeDelivery() {
        System.out.println("Delivery Arranged");
    }
}

// Facade class
class OrderFacade {
    private Order order;
    private Product product;
    private Payment payment;
    private Delivery delivery;

    public OrderFacade() {
        this.order = new Order();
        this.product = new Product();
        this.payment = new Payment();
        this.delivery = new Delivery();
    }

    public void placeOrder() {
        order.create();
        product.checkAvailability();
        payment.processPayment();
        delivery.arrangeDelivery();
    }
}

// Usage of Facade
public class FacadePatternExample {
    public static void main(String[] args) {
        OrderFacade orderFacade = new OrderFacade();
        orderFacade.placeOrder();
    }
}

The Facade pattern, as demonstrated in the online shopping application example, ensures backward compatibility by consolidating complex subsystem interactions (ordering, payment, delivery) behind a simple OrderFacade interface. This allows the underlying subsystems to evolve independently (e.g., changing the payment process or delivery options) without necessitating changes to the client code, thereby preserving the interface's constancy over time. In addition, it makes the code more decoupled, allowing all order steps to be updated independently.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal