Что такое MVP

Ответ

MVP (Model-View-Presenter) — это архитектурный паттерн для разделения логики приложения на три слоя:

  • Model — отвечает за данные и бизнес-логику.
  • View — отображает UI и передает действия пользователя Presenter’у.
  • Presenter — связывает Model и View, обрабатывает логику представления.

Преимущества:

  • Четкое разделение ответственности.
  • Упрощает тестирование (Presenter не зависит от Android API).
  • Уменьшает связность кода.

Пример:

// View (Activity/Fragment)
class MainActivity : AppCompatActivity(), MainView {
    override fun showData(data: String) {
        textView.text = data
    }
}

// Presenter
class MainPresenter(private val view: MainView) {
    fun loadData() {
        val data = Model().getData() // Model
        view.showData(data)
    }
}

// Model
class Model {
    fun getData() = "Hello MVP!"
}

Ответ 18+ 🔞

Э, слушай, вот про эту вашу MVP-архитектуру. Выглядит как очередная модная фигня, но, блядь, если разобраться — а в ней, сука, смысл есть, ёпта.

Представь себе бар. Ты — это View, то есть рожа, которая сидит за стойкой и орёт: «Дайте мне пива!». Твой мозг, который соображает, что пиво — это хорошо, а водка натощак — пиздец, это Presenter. А Model — это, блядь, сам бармен и склад, где всё это добро хранится.

Так вот, суть в чём: чтобы твоя рожа-View не превратилась в манду с ушами, которая и пиво наливает, и соображает, сколько ты уже выпил, и бегает на склад за бочкой. Волнение ебать от одной мысли! Поэтому всё делят:

  • Model (Модель). Это тихий, спокойный чувак на складе или бармен. Его дело — данные. Спросили «Какое пиво есть?» — он отвечает: «Балтика 9, нефильтрованная». Его не ебёт, как ты это пиво будешь пить — из горла или через трубочку. Его дело — знать, что есть.
  • View (Вид). Это ты, твоя рожа и твои руки. Твоя задача — показать, что пиво принесли, и орать «Ещё!», когда стакан пустой. Больше нихуя. Не думать, не считать, просто показывать и кликать.
  • Presenter (Презентер). А вот это, сука, самый главный хитрая жопа. Он сидит посередине. Ты (View) нажал кнопку «Хочу пива!». Presenter слышит это, идёт к Model и говорит: «Э, дай-ка сюда данных, что у нас по пиву?». Model ему отвечает. Дальше Presenter этот ответ, который может быть каким угодно, превращает во что-то понятное для твоей тупой рожи-View. Не «статус: 200, обьект: {название: "Балтика", крепость: 9}», а просто «Вот тебе, мудила, твоё крепкое пиво». И командует View: «Ну показывай уже это пользователю, чего уставился!».

И главная фишка вся в том, что доверия ебать ноль у этих слоёв друг к другу. View не лезет к Model напрямую. Presenter не знает, как именно View рисует кнопки. А Model вообще похуй на всех. И это, блядь, охуенно!

Почему это круто?

  1. Тестировать просто как палку. Хочешь проверить логику? Тестируй Presenter. Он же не привязан к этим вашим Android-шным Activity, которые только и умеют, что впендюрить тебе головную боль. Подсовываешь ему фейковую View и смотришь, какие команды он шлёт. Удивление пиздец — всё работает!
  2. Код не превращается в спагетти. Если у тебя в Activity было овердохуища всего: и загрузка данных, и обработка кликов, и анимации — это пиздопроебибна. С MVP каждый сидит в своей комнате и не мешает друг другу.
  3. Менять View — раз плюнуть. Надоел старый экран? Да похуй. Сделай новый, реализуй тот же интерфейс View, и подсуни его Presenter’у. Presenter даже не заметит подмены, потому что он общается только по контракту.

Ну и пример, чтобы совсем понятно стало, на кой тут этот цирк:

// 1. View (Activity). Тупая рожа, которая только показывает и тыкает.
class MainActivity : AppCompatActivity(), MainContract.View {
    private lateinit var presenter: MainContract.Presenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        presenter = MainPresenter(this, Injection.provideRepository()) // Создаём того самого хитрожопого посредника

        button.setOnClickListener {
            presenter.onButtonClicked() // Тыкнули кнопку — сообщили Presenter'у. ВСЁ.
        }
    }

    // Функция, которую будет дергать Presenter, когда надо что-то показать.
    override fun showData(data: String) {
        textView.text = data // Просто взял и отобразил. Без дум.
    }
}

// 2. Presenter. Мозги операции.
class MainPresenter(
    private val view: MainContract.View,
    private val repository: DataRepository // Это наш доступ к Model
) : MainContract.Presenter {

    override fun onButtonClicked() {
        // View сказала, что кнопку нажали. Пора работать.
        val dataFromModel = repository.getVeryImportantData() // Идём к Model за данными
        val formattedData = "Вот твои данные, чувак: $dataFromModel" // Готовим их для показа (логика представления!)
        view.showData(formattedData) // Командуем View: показывай!
    }
}

// 3. Model (здесь Repository). Бармен на складе.
class DataRepository {
    // Его мир прост и прекрасен.
    fun getVeryImportantData(): String {
        return "Hello MVP!" // Просто возвращает данные. И всё.
    }
}

Короче, если по-простому: MVP — это чтобы не было так, что твой класс Activity сам от себя охуел от нагромождения кода. Всё по полочкам: тупой экран, умный посредник и молчаливый поставщик данных. Ёперный театр, а работает!