โ† Back to Design Patterns
๐Ÿ›๏ธ
Structural

Facade

Provides a simplified interface to a complex subsystem, hiding its internals.

The Problem

A complex library or set of services has many classes, configurations, and entry points. Client code becomes tangled managing all of them directly.

How It Works

  • โ€บReduces coupling between client and complex subsystem
  • โ€บDoesn't seal the subsystem โ€” advanced users can bypass the facade when needed
  • โ€บSingle entry point makes the subsystem easier to use correctly
  • โ€บSimplifies testing โ€” you can mock the facade instead of every subsystem class
  • โ€บCommon when wrapping third-party SDKs to limit exposure to your app

When to Use

โœ“Simplifying a complex library or set of services behind one clean interface
โœ“Layering subsystems to reduce dependencies between them
โœ“Providing sensible defaults for the common case
โœ“Wrapping a third-party SDK so your app is not tightly coupled to it

Real-World Examples

๐ŸŽ
iOS

Alamofire (facade over URLSession stack), AVPlayer wrapper classes

๐Ÿค–
Android

Glide/Picasso (facade over Bitmap/network ops), Retrofit

๐ŸŒ
Web

jQuery (facade over DOM APIs), axios (facade over XMLHttpRequest/fetch)

Code Examples

Swift
// Complex subsystems
class AuthService {
    func login(user: String, pass: String) -> String { "token_abc" }
}
class ProfileService {
    func fetch(token: String) -> [String: String] { ["name": "Agus"] }
}
class CacheService {
    func store(_ key: String, _ value: Any) { }
}

// Facade: one entry point for the whole auth + profile flow
class AppFacade {
    private let auth    = AuthService()
    private let profile = ProfileService()
    private let cache   = CacheService()

    func signIn(username: String, password: String) -> [String: String] {
        let token   = auth.login(user: username, pass: password)
        let data    = profile.fetch(token: token)
        cache.store("profile", data)
        return data
    }
}

// Client only deals with one object
let app = AppFacade()
print(app.signIn(username: "agus", password: "secret"))
// ["name": "Agus"]