Facade: basis van het facadepatroon in mobiele architectuur

Auteur: IT Sectr Gepubliceerd: 2026-02-18 Leestijd: 9 min

Facade is een structureel ontwerppatroon dat een vereenvoudigde interface biedt naar een complex subsysteem van klassen. In mobiele ontwikkeling wordt Facade meestal geïmplementeerd als Service Layer of UseCase, die de interactie met het netwerk, de database en de analytics verbergt. Volgens Martin Fowler (Patterns of Enterprise Application Architecture, 2003) is Facade een van de sleutelpatronen voor het organiseren van de servicelaag.

Belangrijkste punten

  • Facade — structureel patroon dat een eenvoudige interface biedt naar een complex systeem van klassen, bibliotheken of frameworks
  • Service Layer — implementatie van Facade in mobiele architectuur, die API, cache en analytics voor UI verbergt
  • Facade verbergt het subsysteem niet — de client kan er indien nodig rechtstreeks toegang toe krijgen
  • UseCase in Clean Architecture — een variant van Facade die één businessscenario orkestreert
  • Facade vs Adapter: Facade vereenvoudigt de interface, Adapter zet de ene interface om naar de andere

Wat is het Facade-patroon?

Facade — structureel patroon dat een uniforme interface biedt naar een groep interfaces van het subsysteem. Het definieert een interface op hoog niveau die het gebruik van het subsysteem vereenvoudigt. Facade voegt geen nieuwe functionaliteit toe — het orkestreert bestaande componenten en verbergt de complexiteit van hun interactie voor de client.

Kotlin
// Complex subsysteem
class AuthApi {
    suspend fun login(email: String, pass: String): TokenResponse
}

class UserDao {
    suspend fun saveUser(user: UserEntity)
    suspend fun getUser(id: Long): UserEntity?
}

class AnalyticsTracker {
    fun track(event: String, params: Map)
}

// Facade — eenvoudige interface voor UI
class AuthService(
    private val api: AuthApi,
    private val dao: UserDao,
    private val analytics: AnalyticsTracker
) {
    suspend fun loginUser(email: String, password: String): Result {
        return runCatching {
            val token = api.login(email, password)
            val user = User(token.userId, email, token.accessToken)
            dao.saveUser(user.toEntity())
            analytics.track("login_success", mapOf("method" to "email"))
            user
        }
    }
}

AuthService — Facade die AuthApi, UserDao en AnalyticsTracker voor ViewModel verbergt. UI roept loginUser(email, password) aan in plaats van drie afzonderlijke verzoeken naar API, database en analytics. Dit vermindert de koppeling: als AuthApi morgen FirebaseAuth wordt of UserDao migreert naar Room, verandert alleen Facade, niet UI.

Facade in mobiele architectuur: Service Layer

Service Layer — veelvoorkomende implementatie van Facade in mobiele applicaties. Het encapsuleert de businesslogica en de coördinatie tussen lagen. In Android wordt Service Layer vaak geïmplementeerd via UseCase (Clean Architecture), in iOS — via Manager of Service-protocollen.

ComponentRol in het subsysteemWat Facade verbergt
AuthApiNetwerkverzoek naar serverVerzoekformaat, endpoint, HTTP-foutafhandeling
UserDaoLokale opslag van tokenDatabase-schema, SQL-query's, migraties
AnalyticsTrackerVersturen van analytics-gebeurtenissenFirebase/AppMetrica SDK, gebeurtenisformaat
NetworkMonitorControleren van netwerkbeschikbaarheidConnectivityManager, BroadcastReceiver

AuthService verenigt alle vier componenten. ViewModel roept één methode aan, zonder te weten dat er onder de motorkap een netwerkverzoek, een schrijf naar de database, tracking en een netwerkcontrole plaatsvinden. Bij het testen kan AuthService worden vervangen door een mock, waarmee de hele authenticatielogica wordt gecontroleerd zonder integratie met echte componenten.

Facade vs Adapter vs Mediator

Facade, Adapter en Mediator — structurele patronen, maar ze lossen verschillende problemen op. Ze worden vaak verward, omdat alle drie een tussenliggend object introduceren. Laten we de verschillen bekijken aan de hand van een mobiele applicatie.

AspectFacadeAdapterMediator
DoelInterface van subsysteem vereenvoudigenInterface omzettenKoppeling van componenten verminderen
RichtingEén interface → subsysteemClient → AdapteeN componenten ↔ Mediator
Verandering van interfaceCreëert een nieuwe, vereenvoudigdeZet de bestaande omVerandert niet, coördineert
Weet het subsysteem van het patroon?NeeNeeJa, communiceert via Mediator
Voorbeeld in mobiele ontwikkelingUseCase / Service LayerRecyclerView.AdapterCoordinator in iOS

Facade verbergt het subsysteem niet — de client kan indien nodig rechtstreeks toegang krijgen tot AuthApi. Adapter verandert verplicht de interface van Adaptee. Mediator coördineert complexe interacties tussen vele objecten die elkaar misschien niet kennen.

Implementatie van Facade in Kotlin voor Android

De implementatie van Facade in Kotlin voor Android met Clean Architecture gebruikt UseCase als ingangspunt voor elk businessscenario. UseCase is een Facade die de repository, mapper en andere afhankelijkheden voor de UI-laag verbergt.

Kotlin
// Repository — ook Facade, maar één niveau lager
class UserRepositoryImpl(
    private val local: UserLocalDataSource,
    private val remote: UserRemoteDataSource,
    private val mapper: UserMapper
) : UserRepository {
    override suspend fun getUserProfile(id: String): UserProfile {
        val cached = local.getUser(id)
        if (cached != null && !cached.isStale) {
            return mapper.toProfile(cached)
        }
        val dto = remote.fetchUser(id)
        val entity = mapper.toEntity(dto)
        local.saveUser(entity)
        return mapper.toProfile(entity)
    }
}

// UseCase — Facade voor het businessscenario
class LoadUserProfileUseCase(
    private val repo: UserRepository,
    private val analytics: AnalyticsTracker
) {
    suspend operator fun invoke(userId: String): Result {
        return runCatching {
            val profile = repo.getUserProfile(userId)
            analytics.track("profile_loaded", mapOf("user_id" to userId))
            profile
        }
    }
}

LoadUserProfileUseCase — Facade voor het scenario van het laden van een profiel. Het verbergt de cachinglogica (local → remote), de mapping DTO → Entity → Profile en analytics-tracking. ViewModel roept invoke(userId) aan en krijgt een kant-en-klaar UserProfile of een foutmelding. UseCase kan geïsoleerd worden getest door de repository te vervangen door een mock-object.

Implementatie van Facade in Swift voor iOS

Facade in iOS wordt vaak geïmplementeerd als Manager of Service. In tegenstelling tot Android gebruikt iOS protocollen om de interface van Facade te definiëren, waardoor implementaties gemakkelijk kunnen worden uitgewisseld in tests. Laten we een Facade bekijken voor het werken met media — laden, cachen en weergeven.

Swift
protocol MediaServiceProtocol {
    func loadImage(from url: URL) async -> Result<UIImage, Error>
}

final class MediaService: MediaServiceProtocol {
    private let cache: ImageCache
    private let downloader: ImageDownloader
    private let decoder: ImageDecoder
    
    func loadImage(from url: URL) async -> Result<UIImage, Error> {
        // 1. Cache controleren
        if let cached = cache.image(for: url) {
            return .success(cached)
        }
        // 2. Gegevens laden
        let result = await downloader.download(from: url)
        guard case let .success(data) = result else {
            return .failure(MediaError.downloadFailed)
        }
        // 3. Decoderen
        guard let image = decoder.decode(data) else {
            return .failure(MediaError.decodeFailed)
        }
        // 4. In cache opslaan
        cache.setImage(image, for: url)
        return .success(image)
    }
}

MediaService encapsuleert een proces in drie stappen: cache → laden → decoderen. UI roept één methode loadImage(from:) aan in plaats van ImageCache, URLSession en ImageDecoder te beheren. Bij het testen kan MediaServiceProtocol worden vervangen door een mock die vooraf ingestelde afbeeldingen retourneert zonder echt laden.

Veelvoorkomende fouten bij het gebruik van Facade

Fouten bij het ontwerpen van Facade tenietdoen de voordelen ervan: in plaats van vereenvoudiging ontstaat een God Object waarvan het hele systeem afhankelijk is. Laten we drie hoofproblemen bekijken.

God Facade — te veel verantwoordelijkheid

Wanneer één Facade methoden bevat voor authenticatie, het laden van profielen, het versturen van berichten en synchronisatie — is dit een God Object. Kenmerk: 15+ publieke methoden in één klasse. Oplossing: opsplitsen in meerdere gespecialiseerde Facade's per verantwoordelijkheidsgebied — AuthService, ProfileService, MessagingService.

Facade met lekkage van subsysteemdetails

Als Facade types retourneert die specifiek zijn voor het subsysteem (bijvoorbeeld FirebaseUser of RealmObject), blijft de client toch gebonden aan een concrete implementatie. Oplossing: Facade moet alleen eigen types retourneren (data class / struct), waardoor de client volledig wordt geabstraheerd van de details van het subsysteem.

Facade als enige toegangspunt

Wanneer Facade directe toegang tot het subsysteem verbiedt, wordt het een bottleneck. Soms heeft de client een specifieke methode van het subsysteem nodig en is het dwingen om via Facade te gaan overbodig. Facade hoeft geen strikte gatekeeper te zijn: het biedt een handige interface, maar blokkeert geen directe toegang tot componenten.

Veelgestelde vragen

Wat is het verschil tussen Facade en Proxy?

Facade biedt een vereenvoudigde interface naar het subsysteem en creëert vaak een nieuwe set methoden. Proxy behoudt dezelfde interface als het originele object, maar voegt toegangscontrole of lazy loading toe. Facade — voor vereenvoudiging, Proxy — voor controle.

Is Facade hetzelfde als Service Layer?

Service Layer — dit is de implementatie van het Facade-patroon op het niveau van de applicatie-architectuur. Het definieert de grens tussen UI en businesslogica en verbergt de implementatiedetails van services. In Android wordt Service Layer vaak geïmplementeerd via UseCase, in iOS — via Manager of Service-protocollen.

Wanneer wordt Facade een God Object?

God Facade ontstaat wanneer één klasse de verantwoordelijkheid voor meerdere niet-gerelateerde subsystemen op zich neemt. Kenmerken: 15+ publieke methoden, methoden uit verschillende domeinen (authenticatie + betalingen + meldingen), een klasse die moeilijk te testen is (10+ afhankelijkheden). Oplossing: opsplitsen in domein-Facade's.

Is Facade nodig in een kleine applicatie?

In een applicatie met 1-2 schermen is Facade overbodig — directe aanroep van API en database vanuit UI is eenvoudiger en duidelijker. Facade betaalt zich terug bij 5+ schermen en 3+ subsystemen. In middelgrote en kleine projecten is Repository voldoende als enige Facade-laag, zonder extra UseCase-wrapper.

Hoe test je code die Facade gebruikt?

Facade vereenvoudigt testen, omdat het het hele subsysteem vervangt door één mock-object. In plaats van drie componenten te mocken (netwerk + database + analytics) is het mocken van één Facade voldoende. In Swift wordt hiervoor protocol gebruikt, in Kotlin — interface. Facade is ook handig voor integratietests, waarin de orkestratie van componenten wordt gecontroleerd.

Samenvatting

  • Facade — structureel patroon dat een eenvoudige interface biedt naar een complex subsysteem
  • Service Layer en UseCase — veelvoorkomende implementaties van Facade in mobiele architectuur
  • Facade verbergt het subsysteem niet: de client kan indien nodig rechtstreeks toegang krijgen tot componenten
  • Facade vs Adapter: Facade vereenvoudigt, Adapter zet om; Facade vs Mediator: Facade is eenrichtingsverkeer, Mediator is tweerichtingsverkeer
  • God Facade — antipatroon: 15+ methoden in één klasse wijzen op schending van Single Responsibility
  • Protocol/interface voor Facade is verplicht — dit is de enige manier om het subsysteem te mock-testen
  • Aanbeveling: voer Facade in bij 5+ schermen en 3+ subsystemen; voor kleine projecten is Repository voldoende

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook