MVP (Model-View-Presenter) — паттерн архитектуры для разделения логики и интерфейса
MVP — это улучшенная версия MVC, где Presenter заменяет Controller и берет на себя всю бизнес-логику, делая код более тестируемым и поддерживаемым.
🔥 Основные компоненты MVP
Компонент | Роль | Пример в Android/Kotlin |
---|---|---|
Model | Данные и бизнес-логика (например, работа с API, БД). | UserRepository , ApiService |
View | Отображение данных и взаимодействие с пользователем (пассивный слой). | Activity , Fragment , View в iOS |
Presenter | Посредник между Model и View. Обрабатывает события, запрашивает данные, обновляет View. | LoginPresenter |
⚡ Как работает MVP?
- View получает действие пользователя (например, нажатие кнопки).
- View сообщает об этом Presenter.
- Presenter запрашивает данные у Model.
- Model возвращает результат (например, список пользователей).
- Presenter передает данные View для отображения.
🛠 Пример MVP в Android (Kotlin)
1. Model (Repository)
class UserRepository {
fun getUsers(): List<String> {
return listOf("Alice", "Bob", "Charlie") // Данные из "базы"
}
}
2. View (Activity/Fragment)
interface UserView {
fun showUsers(users: List<String>)
}
class UserActivity : AppCompatActivity(), UserView {
private lateinit var presenter: UserPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
presenter = UserPresenter(this, UserRepository())
presenter.loadUsers()
}
override fun showUsers(users: List<String>) {
recyclerView.adapter = UserAdapter(users) // Обновляем UI
}
}
3. Presenter
class UserPresenter(
private val view: UserView,
private val repository: UserRepository
) {
fun loadUsers() {
val users = repository.getUsers()
view.showUsers(users) // Передаем данные во View
}
}
🌟 Преимущества MVP
✅ Тестируемость: Presenter можно тестировать без View (MockView).
✅ Разделение ответственности: View только рисует, Presenter управляет логикой.
✅ Гибкость: Легко заменить View (например, Activity на Fragment).
📉 Недостатки MVP
❌ Boilerplate-код: Нужно создавать интерфейсы для View.
❌ Ручное управление жизненным циклом: Presenter может «пережить» View (риск утечек памяти).
🆚 MVP vs. MVVM
Критерий | MVP | MVVM |
---|---|---|
Связка View-логика | Через интерфейсы | Через Data Binding / LiveData |
Тестируемость | Легко (MockView) | Легко (MockViewModel) |
Поддержка | Ручная | Автоматическая (Android AAC) |
Когда выбирать MVP?
- Для проектов с простым UI (например, утилиты).
- Если нужен полный контроль над логикой.
Когда выбирать MVVM?
- Для сложных UI с частыми обновлениями.
- Если используется Data Binding или Jetpack Compose.
🚀 MVP в других платформах
iOS (Swift)
protocol UserViewProtocol: AnyObject {
func showUsers(_ users: [String])
}
class UserPresenter {
weak var view: UserViewProtocol?
private let repository = UserRepository()
func loadUsers() {
let users = repository.getUsers()
view?.showUsers(users)
}
}
Web (JavaScript)
class UserPresenter {
constructor(view, repository) {
this.view = view;
this.repository = repository;
}
loadUsers() {
const users = this.repository.getUsers();
this.view.showUsers(users);
}
}
💡 Советы по MVP
✔ Используйте DI (Dagger, Koin) для передачи зависимостей в Presenter.
✔ Избегайте утечек:
- В Android:
Presenter
должен держатьweak
ссылку наView
. - В iOS:
weak var view: ViewProtocol?
.
✔ Выносите общую логику в базовыйBasePresenter
.
🔥 Вывод
MVP — это классический паттерн для:
✅ Чистой архитектуры.
✅ Простых и средних проектов.
✅ Платформ без встроенной поддержки MVVM (например, iOS до SwiftUI).
Что учить дальше?
- MVVM (если проект растет).
- Clean Architecture (разделение на слои).
- DI-библиотеки (Dagger 2, Hilt).