Facade: основе обрасца фасада у мобилној архитектури

Аутор: IT Sectr Објављено: 2026-02-18 Време читања: 9 мин

Facade је структурни пројектни образац који пружа поједностављени интерфејс према сложеном подсистему класа. У мобилном развоју Facade се најчешће реализује као Service Layer или UseCase, скривајући интеракцију са мрежом, базом података и аналитиком. Према Martin Fowler-у (Patterns of Enterprise Application Architecture, 2003), Facade је један од кључних образаца за организовање сервисног слоја.

Главно

  • Facade — структурни образац који пружа једноставан интерфејс ка сложеном систему класа, библиотека или фрејмворка
  • Service Layer — реализација обрасца Facade у мобилној архитектури, која скрива API, кеш и аналитику од UI
  • Facade не скрива подсистем — клијент му може приступити директно када је потребно
  • UseCase у Clean Architecture — врста обрасца Facade која оркестрира један пословни сценарио
  • Facade vs Adapter: Facade поједностављује интерфејс, Adapter претвара један интерфејс у други

Шта је образац Facade?

Facade — структурни образац који пружа јединствени интерфејс групи интерфејса подсистема. Он дефинише интерфејс високог нивоа који поједностављује коришћење подсистема. Facade не додаје нову функционалност — он оркестрира постојеће компоненте, скривајући сложеност њихове интеракције од клијента.

Kotlin
// Сложен подсистем
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 — једноставан интерфејс за 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 који скрива AuthApi, UserDao и AnalyticsTracker од ViewModel. UI позива loginUser(email, password) уместо три одвојена захтева ка API, бази података и аналитици. То смањује спрегнутост: ако сутра AuthApi постане FirebaseAuth или UserDao мигрира на Room, промениће се само Facade, а не UI.

Facade у мобилној архитектури: Service Layer

Service Layer — честа реализација обрасца Facade у мобилним апликацијама. Он инкапсулира пословну логику и координацију између слојева. На Android-у се Service Layer често реализује преко UseCase (Clean Architecture), а на iOS-у — преко Manager или Service протокола.

КомпонентаУлога у подсистемуШта Facade скрива
AuthApiМрежни захтев ка серверуФормат захтева, endpoint, обраду HTTP грешака
UserDaoЛокално чување токенаШему базе података, SQL упите, миграције
AnalyticsTrackerСлање аналитичких догађајаFirebase/AppMetrica SDK, формат догађаја
NetworkMonitorПровера доступности мрежеConnectivityManager, BroadcastReceiver

AuthService обједињује све четири компоненте. ViewModel позива један метод, не знајући да се испод хаубе дешавају мрежни захтев, упис у базу, праћење и провера мреже. При тестирању AuthService се може заменити mock-ом, проверавајући целокупну логику ауторизације без интеграције са стварним компонентама.

Facade vs Adapter vs Mediator

Facade, Adapter и Mediator — структурни обрасци, али решавају различите задатке. Често се мешају, јер сва три уводе посреднички објекат. Размотримо разлике на примеру мобилне апликације.

АспектFacadeAdapterMediator
ЦиљПоједноставити интерфејс подсистемаПретворити интерфејсСмањити спрегнутост компоненти
СмерЈедан интерфејс → подсистемКлијент → AdapteeN компоненти ↔ Mediator
Измена интерфејсаСтвара нови, поједностављениПретвара постојећиНе мења, координира
Да ли подсистем зна за образац?НеНеДа, комуницира преко Mediator
Пример у мобилном развојуUseCase / Service LayerRecyclerView.AdapterCoordinator на iOS-у

Facade не скрива подсистем — клијент може директно да приступи AuthApi када је потребно. Adapter обавезно мења интерфејс Adaptee. Mediator координира сложене интеракције између бројних објеката који можда не знају један за другог.

Реализација обрасца Facade на Kotlin за Android

Реализација обрасца Facade на Kotlin за Android са Clean Architecture користи UseCase као улазну тачку за сваки пословни сценарио. UseCase — то је Facade који скрива репозиторијум, мапер и друге зависности од UI слоја.

Kotlin
// Repository — такође Facade, али један ниво ниже
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 за пословни сценарио
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 за сценарио учитавања профила. Он скрива логику кеширања (local → remote), мапирање DTO → Entity → Profile и праћење аналитике. ViewModel позива invoke(userId) и добија готов UserProfile или грешку. UseCase се може тестирати изоловано, замењујући репозиторијум mock објектом.

Реализација обрасца Facade на Swift за iOS

Facade на iOS-у се често реализује као Manager или Service. За разлику од Android-а, iOS користи протоколе за дефинисање интерфејса Facade, што омогућава лако замењивање имплементација у тестовима. Размотримо Facade за рад са медијима — учитавање, кеширање и приказ.

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. Проверити кеш
        if let cached = cache.image(for: url) {
            return .success(cached)
        }
        // 2. Учитати податке
        let result = await downloader.download(from: url)
        guard case let .success(data) = result else {
            return .failure(MediaError.downloadFailed)
        }
        // 3. Декодовати
        guard let image = decoder.decode(data) else {
            return .failure(MediaError.decodeFailed)
        }
        // 4. Сачувати у кеш
        cache.setImage(image, for: url)
        return .success(image)
    }
}

MediaService инкапсулира трокорачни процес: кеш → учитавање → декодовање. UI позива један метод loadImage(from:) уместо управљања ImageCache, URLSession и ImageDecoder. При тестирању се MediaServiceProtocol може заменити mock-ом који враћа унапред припремљене слике без стварног учитавања.

Типичне грешке при коришћењу обрасца Facade

Грешке при пројектовању Facade поништавају његове предности: уместо поједностављења добија се God Object од кога зависи цео систем. Размотримо три главна проблема.

God Facade — превише одговорности

Када један Facade садржи методе за ауторизацију, учитавање профила, слање порука и синхронизацију — то је God Object. Ознака: 15+ јавних метода у једној класи. Решење: поделити на неколико специјализованих Facade према областима одговорности — AuthService, ProfileService, MessagingService.

Facade са цурењем детаља подсистема

Ако Facade враћа типове специфичне за подсистем (на пример, FirebaseUser или RealmObject), клијент је ипак везан за конкретну имплементацију. Решење: Facade треба да враћа само сопствене типове (data class / struct), потпуно апстрахујући клијента од детаља подсистема.

Facade као једина улазна тачка

Када Facade забрањује директан приступ подсистему, постаје уско грло. Понекад клијенту је потребан специфичан метод подсистема, па је приморавати га да пролази кроз Facade сувишно. Facade не треба да буде строг чувар: он пружа згодан интерфејс, али не блокира директан приступ компонентама.

Често постављана питања

Која је разлика између Facade и Proxy?

Facade пружа поједностављени интерфејс ка подсистему, често стварајући нови скуп метода. Proxy задржава исти интерфејс као оригинални објекат, али додаје контролу приступа или лењо учитавање. Facade — за поједностављење, Proxy — за контролу.

Да ли је Facade исто што и Service Layer?

Service Layer — то је имплементација обрасца Facade на нивоу архитектуре апликације. Он дефинише границу између UI и пословне логике, скривајући детаље имплементације сервиса. На Android-у се Service Layer често реализује преко UseCase, на iOS-у — преко Manager или Service протокола.

Када Facade постаје God Object?

God Facade настаје када једна класа преузме одговорност за неколико неповезаних подсистема. Ознаке: 15+ јавних метода, методе из различитих домена (ауторизација + плаћања + обавештења), класа коју је тешко тестирати (10+ зависности). Решење: поделити на доменске Facade.

Да ли је Facade потребан у малој апликацији?

У апликацији са 1-2 екрана Facade је сувишан — директан позив API и базе података из UI је једноставнији и јаснији. Facade се исплати при 5+ екрана и 3+ подсистема. У средњим и малим пројектима довољан је Repository као једини Facade слој, без додатног омотача UseCase.

Како тестирати код који користи Facade?

Facade поједностављује тестирање, јер замењује цео подсистем једним mock објектом. Уместо mock три компоненте (мрежа + база + аналитика) довољно је mock једног Facade. На Swift-у се за то користи protocol, на Kotlin-у — interface. Facade је згодан и за интеграционе тестове, где се проверава оркестрација компоненти.

Закључак

  • Facade — структурни образац који пружа једноставан интерфејс ка сложеном подсистему
  • Service Layer и UseCase — честе имплементације обрасца Facade у мобилној архитектури
  • Facade не скрива подсистем: клијент може директно приступити компонентама када је потребно
  • Facade vs Adapter: Facade поједностављује, Adapter претвара; Facade vs Mediator: Facade је једносмеран, Mediator је двосмеран
  • God Facade — антиобразац: 15+ метода у једној класи указује на кршење Single Responsibility
  • Протокол/интерфејс за Facade је обавезан — то је једини начин mock тестирања подсистема
  • Препорука: уводите Facade при 5+ екрана и 3+ подсистема; за мале пројекте довољан је Repository

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође