Sobes.tech
Middle

Запознат ли сте с патърна за дизайн Facade? Разкажете за опита си с неговото използване.

sobes.tech AI

Отговор от AI

Да, запознат съм с патърна за дизайн Facade. Това е структурен патърн, който предоставя унифициран интерфейс към сложна подсистема от класове. Целта му е да опрости използването на подсистемата, като скрие нейната сложност от клиента.

Имам опит с използването на патърна Facade, например при работа с многоуровнева архитектура на приложение. Представете си модул за работа с мрежа и база данни. Вместо клиентският код да взаимодейства директно с класове на мрежовия слой (Retrofit, OkHttp), парсери, класове за база данни (Room, DAO), е реализиран клас-фасада. Тази фасада предоставя прости методи, например getUser(userId) или saveUser(user), които вътрешно координират взаимодействието с съответните подсистеми: правят мрежов заявка, парсират данните, съхраняват ги в базата данни.

Предимства на такъв подход:

  • Улесняване на клиентския код: Клиентът не трябва да знае за вътрешната структура на подсистемата.
  • Намаляване на свързаността: Фасадата отделя клиента от конкретните реализации на подсистемата, което улеснява тяхната замяна.
  • Подобряване на структурираността: Подсистемата става по-управляема и разбираема.

Пример за опростена реализация на фасада:

// Подсистема за работа с API
class ApiService {
    fun getUserFromApi(userId: Int): String {
        // Логика за мрежова заявка
        return "{\"id\":$userId, \"name\":\"John Doe\"}"
    }
}

// Подсистема за работа с БД
class DatabaseService {
    fun saveUserToDb(userJson: String) {
        // Логика за съхранение в БД
    }

    fun getUserFromDb(userId: Int): String {
        // Логика за получаване от БД
        return "" // Заглушка
    }
}

// Фасада
class UserFacade(
    private val apiService: ApiService,
    private val databaseService: DatabaseService
) {
    fun getUser(userId: Int): String {
        // Първо опитваме да получим от БД
        val userFromDb = databaseService.getUserFromDb(userId)
        if (userFromDb.isNotEmpty()) {
            return userFromDb
        }

        // Ако няма в БД, получаваме от API
        val userFromApi = apiService.getUserFromApi(userId)

        // Запазваме в БД за кеширане
        databaseService.saveUserToDb(userFromApi)

        return userFromApi
    }
}

// Пример за използване на фасадата в клиентски код
fun main() {
    val apiService = ApiService()
    val databaseService = DatabaseService()
    val userFacade = UserFacade(apiService, databaseService)

    val userJson = userFacade.getUser(123)
    println(userJson)
}

В този пример UserFacade скрива детайлите за получаване на данни за потребителя от API и съхраняването им в БД, предоставяйки на клиентския код простия метод getUser. Клиентът не трябва да знае за съществуването на ApiService и DatabaseService.

По този начин, Facade помага да се създаде по-чист, разбираем и лесен за поддръжка код, особено при работа с комплексни модули.