Назад к вопросам
Middle
71
questionbank

Можешь подробно рассказать о паттерне MVP (Model-View-Presenter)?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Разделяет приложение на три основных компонента:

  • Model: Представляет данные и бизнес-логику. Не знает ничего о View или Presenter.
  • View: Отвечает за отображение данных и взаимодействие с пользователем. Пассивен, не содержит логики принятия решений. Делегирует все действия пользователя Presenter'у.
  • Presenter: Выступает посредником между Model и View. Обрабатывает действия пользователя, извлекает данные из Model и обновляет View. Содержит логику представления.

Плюсы:

  • Улучшенная тестируемость (логика Presenter'а легко тестируется изолированно).
  • Разделение ответственности.
  • Переиспользование логики представления (в разном View).

Минусы:

  • Увеличение количества классов.
  • boilerplate-код (интерфейсы View, Presenter'а).

Взаимодействие:

  1. View сообщает Presenter'у о действиях пользователя.
  2. Presenter взаимодействует с Model (получает/сохраняет данные, выполняет бизнес-логику).
  3. Presenter получает результат от Model.
  4. Presenter обновляет View, вызывая его методы.

Пример:

// Интерфейс View
interface MainView {
    void showProgress();
    void hideProgress();
    void displayData(String data);
    void showError(String message);
}

// Интерфейс Presenter
interface MainPresenter {
    void attachView(MainView view);
    void detachView();
    void fetchData();
}

// Реализация View (Activity/Fragment)
public class MainActivity extends AppCompatActivity implements MainView {
    private MainPresenter presenter;
    // ... реализация методов интерфейса
}

// Реализация Presenter
public class MainPresenterImpl implements MainPresenter {
    private MainView view;
    private Model model; // Ссылка на Model

    @Override
    public void attachView(MainView view) {
        this.view = view;
        this.model = new ModelImpl(); // Инициализация Model
    }

    @Override
    public void detachView() {
        this.view = null;
        this.model = null;
    }

    @Override
    public void fetchData() {
        if (view != null) {
            view.showProgress();
            // Запрос данных из Model
            model.getData(new Model.DataCallback() {
                @Override
                public void onSuccess(String data) {
                    if (view != null) {
                        view.hideProgress();
                        view.displayData(data);
                    }
                }

                @Override
                public void onError(String message) {
                    if (view != null) {
                        view.hideProgress();
                        view.showError(message);
                    }
                }
            });
        }
    }
}

// Простая Model
interface Model {
    interface DataCallback {
        void onSuccess(String data);
        void onError(String message);
    }
    void getData(DataCallback callback);
}

class ModelImpl implements Model {
    @Override
    public void getData(DataCallback callback) {
        // Имитация получения данных
        new Handler().postDelayed(() -> {
            callback.onSuccess("Данные из Model");
        }, 1000);
    }
}