Facade: The Hotel Reception Pattern
DEV Community

Facade: The Hotel Reception Pattern

You check into a hotel. You want a room sorted, a taxi booked, dinner reserved, and a wake-up call. Do you hunt down the housekeeping department, then the transport desk, then the kitchen, then the operator, one at a time? No. You call reception and say "sort all this out." Reception knows who to call behind the scenes. You talk to one person instead of five. That's the Facade pattern: one simple front door that hides a messy, complicated system behind it.

The Problem

Say placing an order actually involves four subsystems, in a specific order:

// Every caller has to know ALL of this, in the RIGHT sequence
var inventory = new InventoryService();
if (!inventory.CheckStock(itemId)) return;
inventory.Reserve(itemId);
var payment = new PaymentService();
payment.Charge(customerId, amount);
var shipping = new ShippingService();
var trackingId = shipping.Schedule(itemId, address);
var notifier = new EmailService();
notifier.Send(customerId, $"Order placed! Track: {trackingId}");

Every place that needs to place an order repeats all of this - every service, every method, the exact sequence. Change the steps once and you're editing it everywhere.

The Facade

Wrap the whole mess behind one class with one simple method:

public class OrderFacade
{
    private readonly InventoryService _inventory = new();
    private readonly PaymentService _payment = new();
    private readonly ShippingService _shipping = new();
    private readonly EmailService _email = new();

    // one simple door
    public void PlaceOrder(int customerId, int itemId, decimal amount, string address)
    {
        if (!_inventory.CheckStock(itemId)) throw new Exception("Out of stock");
        _inventory.Reserve(itemId);
        _payment.Charge(customerId, amount);
        var trackingId = _shipping.Schedule(itemId, address);
        _email.Send(customerId, $"Order placed! Track: {trackingId}");
    }
}

Now the caller's entire job is one line:

var order = new OrderFacade();
order.PlaceOrder(customerId: 1, itemId: 42, amount: 999, address: "Bengaluru");

The caller has no idea there are four services and a specific sequence behind it - exactly like the hotel guest has no idea reception rang four departments.

Key Insight

The subsystems still exist and still work as before. The Facade doesn't remove complexity - it hides it behind a clean entry point. And it isn't a wall: if some advanced caller genuinely needs PaymentService directly, it's still there. The Facade is a convenience, not a lockdown.

Facade vs Adapter

Both wrap, but with different purposes. This is the confusion worth clearing up:

  • Adapter wraps one thing to change its shape so it fits somewhere it didn't before. Purpose: compatibility.
  • Facade wraps many things to give one simple entry point. Purpose: simplicity.

Adapter is one object with a different shape. Facade is many objects behind one easy door.

Where You've Already Seen It

HttpClient is a facade. Behind that one friendly class sits DNS resolution, sockets, TLS handshakes, and connection pooling. You just call GetAsync() and none of that surfaces. Most well-designed "Service" classes in an app are facades too - a clean method on top of repositories, validators, and mappers.

One Line to Remember

Facade = hotel reception. One simple door in front; it coordinates the messy departments behind the scenes.

Part 6 of a series on must-know design patterns in C#, explained the simple way. Earlier parts covered Singleton, Factory Method, Builder, Adapter, and Decorator. Next up: Proxy - the bodyguard pattern.

Top comments (0)

Comments

No comments yet. Start the discussion.