Приведите пример применения GoF-паттернов в Android SDK.android-227

1. Observer - LiveData

Суть паттерна: Определяет зависимость "один-ко-многим" между объектами, чтобы при изменении состояния одного объекта все зависящие от него объекты автоматически уведомлялись и обновлялись.

Пример в Android:

class StockViewModel : ViewModel() {
    private val _price = MutableLiveData<Double>()
    val price: LiveData<Double> = _price // Observable

    fun updatePrice(newPrice: Double) {
        _price.value = newPrice
    }
}

// Observer
viewModel.price.observe(this) { price ->
    updatePriceTextView(price)
}

2. Singleton - getSystemService

Суть паттерна: Гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к нему.

Пример в Android:

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE)
        as ConnectivityManager
// Всегда возвращает один и тот же экземпляр сервиса

3. Adapter - RecyclerView.Adapter

Суть паттерна: Преобразует интерфейс класса в другой интерфейс, ожидаемый клиентом.

Пример в Android:

class ProductAdapter(private val items: List<Product>) :
    RecyclerView.Adapter<ProductAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        // Адаптация данных к View
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_product, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(items[position])
    }
}

4. Factory Method - LayoutInflater

Суть паттерна: Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать.

Пример в Android:

val view = LayoutInflater.from(context)
    .inflate(R.layout.custom_view, parent, false)
// Создает View соответствующего типа на основе XML

5. Command - Handler.post

Суть паттерна: Инкапсулирует запрос как объект, позволяя параметризовать клиенты с другими запросами, ставить запросы в очередь или протоколировать их.

Пример в Android:

val handler = Handler(Looper.getMainLooper())
handler.post {
    // Команда для выполнения в UI потоке
    updateUI()
}

6. Decorator - ContextWrapper

Суть паттерна: Динамически добавляет объекту новые обязанности.

Пример в Android:

val wrappedContext = ContextThemeWrapper(
    originalContext,
    R.style.AppTheme
)
// Добавляет тему к существующему контексту

7. Template Method - AsyncTask

Суть паттерна: Определяет скелет алгоритма, перекладывая ответственность за некоторые его шаги на подклассы.

Пример в Android:

class DownloadTask : AsyncTask<URL, Int, File>() {
    override fun doInBackground(vararg urls: URL): File {
        // Реализация фоновой задачи
    }

    override fun onPostExecute(result: File) {
        // Обработка результата в UI потоке
    }
}

8. Proxy - Binder

Суть паттерна: Предоставляет объект-заместитель, который контролирует доступ к другому объекту.

Пример в Android:

AIDL (Android Interface Definition Language) использует Proxy
для межпроцессного взаимодействия

9. Strategy - Animation Interpolators

Суть паттерна: Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми.

Пример в Android:

val animation = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f).apply {
    interpolator = AccelerateDecelerateInterpolator() // Стратегия анимации
    duration = 300
    start()
}

10. Builder - AlertDialog.Builder

Суть паттерна: Отделяет конструирование сложного объекта от его представления.

Пример в Android:

AlertDialog.Builder(this)
    .setTitle("Confirm")
    .setMessage("Are you sure?")
    .setPositiveButton("Yes") { _, _ -> confirm() }
    .setNegativeButton("No") { dialog, _ -> dialog.dismiss() }
    .create()
    .show()

Резюмируем:

Android SDK активно использует паттерны проектирования GoF для решения типичных задач. Наиболее часто встречаются Observer (LiveData), Adapter (RecyclerView), Factory Method (LayoutInflater) и Builder (AlertDialog). Понимание этих паттернов помогает лучше разбираться в архитектуре Android и писать более качественный код.