Facade : les bases du patron façade dans l'architecture mobile

Auteur : IT Sectr Publié le : 2026-02-18 Temps de lecture : 9 min

Facade est un patron de conception structurel qui fournit une interface simplifiée à un sous-système complexe de classes. Dans le développement mobile, Facade est le plus souvent implémenté comme un Service Layer ou un UseCase, masquant l'interaction avec le réseau, la base de données et l'analytique. Selon Martin Fowler (Patterns of Enterprise Application Architecture, 2003), Facade est l'un des patrons clés pour organiser la couche de services.

L'essentiel

  • Facade — patron structurel qui fournit une interface simple à un système complexe de classes, de bibliothèques ou de frameworks
  • Service Layer — implémentation de Facade dans l'architecture mobile qui masque l'API, le cache et l'analytique à la UI
  • Facade ne masque pas le sous-système — le client peut y accéder directement si nécessaire
  • UseCase dans Clean Architecture — une variante de Facade qui orchestre un seul scénario métier
  • Facade vs Adapter : Facade simplifie l'interface, Adapter transforme une interface en une autre

Qu'est-ce que le patron Facade ?

Facade est un patron structurel qui fournit une interface unifiée à un groupe d'interfaces du sous-système. Il définit une interface de haut niveau qui simplifie l'utilisation du sous-système. Facade n'ajoute pas de nouvelle fonctionnalité — il orchestre les composants existants, masquant la complexité de leur interaction au client.

Kotlin
// Sous-système complexe
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 — une interface simple pour la 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 est une Facade qui masque AuthApi, UserDao et AnalyticsTracker au ViewModel. La UI appelle loginUser(email, password) au lieu de trois requêtes séparées vers l'API, la base de données et l'analytique. Cela réduit le couplage : si demain AuthApi devient FirebaseAuth ou si UserDao migre vers Room, seule la Facade change, pas la UI.

Facade dans l'architecture mobile : Service Layer

Service Layer est une implémentation courante de Facade dans les applications mobiles. Il encapsule la logique métier et la coordination entre les couches. Dans Android, le Service Layer est souvent implémenté via UseCase (Clean Architecture), et dans iOS via les protocoles Manager ou Service.

Composant Rôle dans le sous-système Ce que masque Facade
AuthApi Requête réseau vers le serveur Format de la requête, endpoint, gestion des erreurs HTTP
UserDao Stockage local du jeton Schéma de la base de données, requêtes SQL, migrations
AnalyticsTracker Envoi des événements d'analytique SDK Firebase/AppMetrica, format des événements
NetworkMonitor Vérification de la disponibilité du réseau ConnectivityManager, BroadcastReceiver

AuthService combine les quatre composants. Le ViewModel appelle une seule méthode sans savoir que, sous le capot, se produisent une requête réseau, une écriture en base de données, un suivi et une vérification du réseau. Lors des tests, AuthService peut être remplacé par un mock, vérifiant toute la logique d'authentification sans intégration avec les composants réels.

Facade vs Adapter vs Mediator

Facade, Adapter et Mediator sont des patrons structurels, mais ils résolvent des problèmes différents. On les confond souvent, car tous les trois introduisent un objet intermédiaire. Analysons les différences à l'aide d'un exemple d'application mobile.

Aspect Facade Adapter Mediator
Objectif Simplifier l'interface du sous-système Transformer une interface Réduire le couplage entre les composants
Direction Une interface → sous-système Client → Adaptee N composants ↔ Mediator
Modification de l'interface Crée une nouvelle, simplifiée Transforme l'existante Ne modifie pas, coordonne
Le sous-système connaît-il le patron ? Non Non Oui, communique via le Mediator
Exemple dans le développement mobile UseCase / Service Layer RecyclerView.Adapter Coordinator dans iOS

Facade ne masque pas le sous-système — le client peut accéder à AuthApi directement si nécessaire. Adapter modifie obligatoirement l'interface de l'Adaptee. Mediator coordonne les interactions complexes entre de nombreux objets qui peuvent ne pas se connaître.

Implémentation de Facade en Kotlin pour Android

L'implémentation de Facade en Kotlin pour Android avec Clean Architecture utilise UseCase comme point d'entrée pour chaque scénario métier. UseCase est une Facade qui masque le repository, le mapper et les autres dépendances à la couche UI.

Kotlin
// Repository est aussi une Facade, mais à un niveau inférieur
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 — une Facade pour le scénario métier
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 est une Facade pour le scénario de chargement de profil. Il masque la logique de mise en cache (local → remote), le mapping DTO → Entity → Profile et le suivi d'analytique. Le ViewModel appelle invoke(userId) et reçoit un UserProfile prêt ou une erreur. UseCase peut être testé de manière isolée en remplaçant le repository par un objet mock.

Implémentation de Facade en Swift pour iOS

Facade dans iOS est souvent implémenté comme un Manager ou un Service. Contrairement à Android, iOS utilise des protocoles pour définir l'interface de Facade, ce qui permet de remplacer facilement les implémentations dans les tests. Examinons une Facade pour travailler avec les médias — chargement, mise en cache et affichage.

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. Vérifier le cache
        if let cached = cache.image(for: url) {
            return .success(cached)
        }
        // 2. Charger les données
        let result = await downloader.download(from: url)
        guard case let .success(data) = result else {
            return .failure(MediaError.downloadFailed)
        }
        // 3. Décoder
        guard let image = decoder.decode(data) else {
            return .failure(MediaError.decodeFailed)
        }
        // 4. Enregistrer dans le cache
        cache.setImage(image, for: url)
        return .success(image)
    }
}

MediaService encapsule un processus en trois étapes : cache → chargement → décodage. La UI appelle une seule méthode loadImage(from:) au lieu de gérer ImageCache, URLSession et ImageDecoder. Lors des tests, MediaServiceProtocol peut être remplacé par un mock renvoyant des images prédéfinies sans chargement réel.

Erreurs typiques lors de l'utilisation de Facade

Les erreurs dans la conception de Facade annulent ses avantages : au lieu d'une simplification, on obtient un God Object dont dépend tout le système. Analysons les trois principaux problèmes.

God Facade — trop de responsabilité

Lorsqu'une seule Facade contient des méthodes d'authentification, de chargement de profil, d'envoi de messages et de synchronisation — c'est un God Object. Signe : plus de 15 méthodes publiques dans une classe. Solution : le diviser en plusieurs Facades spécialisées par domaines de responsabilité — AuthService, ProfileService, MessagingService.

Facade avec fuite des détails du sous-système

Si la Facade renvoie des types spécifiques au sous-système (par exemple, FirebaseUser ou RealmObject), le client reste lié à une implémentation concrète. Solution : la Facade doit renvoyer uniquement ses propres types (data class / struct), en abstrayant complètement le client des détails du sous-système.

Facade comme point d'entrée unique

Lorsque la Facade interdit l'accès direct au sous-système, elle devient un goulot d'étranglement. Parfois, le client a besoin d'une méthode spécifique du sous-système, et le forcer à passer par la Facade est redondant. Facade ne doit pas être un gatekeeper strict : elle fournit une interface pratique, mais ne bloque pas l'accès direct aux composants.

Questions fréquentes

Quelle est la différence entre Facade et Proxy ?

Facade fournit une interface simplifiée au sous-système, créant souvent un nouvel ensemble de méthodes. Proxy conserve la même interface que l'objet original, mais ajoute un contrôle d'accès ou un chargement paresseux. Facade sert à simplifier, Proxy à contrôler.

Facade est-il la même chose que Service Layer ?

Service Layer est une implémentation du patron Facade au niveau de l'architecture de l'application. Il définit la frontière entre la UI et la logique métier, masquant les détails d'implémentation des services. Dans Android, le Service Layer est souvent implémenté via UseCase ; dans iOS, via les protocoles Manager ou Service.

Quand Facade devient-il un God Object ?

God Facade apparaît lorsqu'une classe prend la responsabilité de plusieurs sous-systèmes sans lien. Signes : plus de 15 méthodes publiques, des méthodes de domaines différents (authentification + paiements + notifications), une classe difficile à tester (plus de 10 dépendances). Solution : diviser en Facades de domaine.

Facade est-il nécessaire dans une petite application ?

Dans une application avec 1-2 écrans, Facade est redondant — appeler l'API et la base de données directement depuis la UI est plus simple et plus clair. Facade est rentable avec 5+ écrans et 3+ sous-systèmes. Dans les projets petits et moyens, un Repository comme unique couche Facade suffit, sans wrapper UseCase supplémentaire.

Comment tester du code qui utilise Facade ?

Facade simplifie les tests, car il remplace tout un sous-système par un seul objet mock. Au lieu de mocker trois composants (réseau + base de données + analytique), il suffit de mocker une Facade. En Swift, on utilise des protocoles pour cela ; en Kotlin, des interfaces. Facade est également pratique pour les tests d'intégration qui vérifient l'orchestration des composants.

Résumé

  • Facade — patron structurel qui fournit une interface simple à un sous-système complexe
  • Service Layer et UseCase — implémentations courantes de Facade dans l'architecture mobile
  • Facade ne masque pas le sous-système : le client peut accéder aux composants directement si nécessaire
  • Facade vs Adapter : Facade simplifie, Adapter transforme ; Facade vs Mediator : Facade est unidirectionnel, Mediator est bidirectionnel
  • God Facade — antipatron : plus de 15 méthodes dans une classe signalent une violation du Single Responsibility
  • Protocole/interface pour Facade est obligatoire — c'est la seule façon de tester le sous-système avec des mocks
  • Recommandation : introduisez Facade avec 5+ écrans et 3+ sous-systèmes ; pour les petits projets, Repository suffit

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi