Facade: The Hotel Reception Pattern

작성자

카테고리:

← 피드로
DEV Community · Vignesh Athiappan · 2026-07-28 개발(SW)

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: the caller has to know everything

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}");

Enter fullscreen mode Exit fullscreen mode

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}");
    }
}

Enter fullscreen mode Exit fullscreen mode

Now the caller’s entire job is one line:

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

Enter fullscreen mode Exit fullscreen mode

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.

The 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, different purpose

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.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다