Настройка архитектуры MVP для Android-приложения
MVP на Android — паттерн с историей. До Architecture Components он был стандартом де-факто: отделял логику от Activity через интерфейс Presenter. Сейчас его выбирают для проектов на Java, где переход на Kotlin + ViewModel нецелесообразен, или там, где команда хорошо знает паттерн и менять его дорого.
Структура MVP в Android-контексте
Три участника: Model (данные и бизнес-логика), View (интерфейс, который реализует Activity или Fragment), Presenter (управляет логикой, не знает об Android SDK).
public interface ProfileContract {
interface View {
void showProfile(UserProfile profile);
void showError(String message);
void showLoading(boolean show);
}
interface Presenter {
void loadProfile(String userId);
void onDestroy();
}
}
public class ProfilePresenter implements ProfileContract.Presenter {
private final ProfileContract.View view;
private final UserRepository repository;
private CompositeDisposable disposables = new CompositeDisposable();
public ProfilePresenter(ProfileContract.View view, UserRepository repository) {
this.view = view;
this.repository = repository;
}
@Override
public void loadProfile(String userId) {
view.showLoading(true);
disposables.add(
repository.getProfile(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
profile -> { view.showLoading(false); view.showProfile(profile); },
error -> { view.showLoading(false); view.showError(error.getMessage()); }
)
);
}
@Override
public void onDestroy() { disposables.clear(); }
}
Activity реализует ProfileContract.View, создаёт Presenter в onCreate, вызывает presenter.onDestroy() в onDestroy.
Проблема поворота экрана
Это главный недостаток MVP по сравнению с MVVM: Presenter не переживает пересоздание Activity. Решения: хранить Presenter через retain Fragment (устарело), через ViewModelStore (ирония — используем ViewModel как контейнер для Presenter), или принять утрату состояния и перезагружать данные.
В проектах, где MVP устоялся, часто выбирают второй путь: RetainedPresenterFragment без UI, который хранит Presenter в setRetainInstance(true). Работает, но выглядит как костыль.
Когда MVP уместен
Legacy Java-проект без планов на Kotlin. Команда, знакомая с паттерном. Проект с небольшим числом экранов, где overhead MVVM + StateFlow не оправдан.
Для нового проекта на Kotlin — MVVM + ViewModel предпочтительнее: лучше интеграция с Jetpack, нет проблем с rotation, чище тестирование.
Что входит в настройку
Создание базовой структуры контрактов (View/Presenter интерфейсы). Настройка базового класса BasePresenter с управлением жизненным циклом. Подключение DI через Dagger 2. Образцовый модуль с тестами Presenter через JUnit + Mockito без Android-зависимостей.
Сроки
Настройка MVP-структуры с нуля: 2–3 дня. Рефакторинг существующего проекта: 1–2 недели в зависимости от объёма. Стоимость — по результатам анализа кода.







