MVP — bu nima, Model-View-Presenter namunasi iOS va Android-da

Muallif: IT Sectr Nashr etilgan: 2026-02-16 O'qish vaqti: 10 daq

MVP (Model-View-Presenter) — Presenter ViewContract interfeysi orqali Model va View o'rtasida vositachi bo'lib xizmat qiladigan arxitektura namunasi. MVC dan farqli o'laroq, bunda Controller to'g'ridan-to'g'ri UIKit orqali View ni boshqaradi, Presenter freymvorkka bog'liq emas — abstraksiya orqali ishlaydi, bu uni Android SDK yoki UIKit siz test qilinadigan qiladi. MVP Android ishlanmasida Jetpack paydo bo'lishidan oldin keng qo'llanilgan va legacy loyihalar uchun dolzarb bo'lib qolmoqda. Batafsil Martin Faulerning maqolasida.

Asosiy

  • MVP — uch komponent: Model (ma'lumotlar), View (interfeys), Presenter (mantiq va holat)
  • ViewContract — Presenter View bilan bog'lanadigan interfeys, test qilinishni ta'minlaydi
  • Presenter — barcha biznes mantiqni o'z ichiga oladi, Android/iOS platforma sinflariga bog'liq emas
  • Passive View — View maksimal passiv, faqat Presenter buyruqlari bo'yicha ma'lumotlarni ko'rsatadi
  • MVP vs MVC — Presenter unit-testlar bilan tekshiriladi, MVC dagi Controller UIKit/Android Framework ga bog'liq

MVP nima: Model-View-Presenter namunasining mohiyati

MVP (Model-View-Presenter) — 2000-yillarning boshida Martin Fauler tomonidan foydalanuvchi interfeysining test qilinishini yaxshilash uchun MVC ning evolyutsiyasi sifatida taklif qilingan arxitektura namunasi. Model ma'lumotlar va biznes mantiqni boshqaradi, View ko'rsatish va foydalanuvchi kiritishini qayta ishlash uchun javobgar, Presenter — View dan hodisalarni oladigan, Model dan ma'lumotlarni chiqaradigan va ko'rsatish uchun holatni shakllantiradigan markaziy komponent.

MVP ni MVC dan asosiy farqi — Presenter View ga to'g'ridan-to'g'ri havolaga ega emas. Buning o'rniga Presenter ViewContract interfeysi orqali View bilan o'zaro aloqa qiladi. View bu interfeysni amalga oshiradi va o'zini Presenter ga uzatadi. Bu UIKit (iOS) yoki Android Framework ga bog'liqlikni uzadi — Presenter ViewContract ning mock amalga oshirilishi bilan izolyatsiya qilingan holda test qilinadi. MVC da controller UIViewController to'g'ridan-to'g'ri UILabel ni yangilaydi, MVP da Presenter view.showName(name) metodini chaqiradi, View esa qanday ko'rsatishni hal qiladi.

KomponentMas'uliyatTest qilinish
ModelMa'lumotlar, biznes mantiq, tarmoq chaqiruvlariUnit-testlar (UI ga bog'liq emas)
ViewUI ni ko'rsatish, hodisalarni Presenter ga uzatishInterfeys orqali mock amalga oshirish
PresenterBiznes mantiq, holatni boshqarish, navigatsiyaUnit-testlar (ViewContract mock orqali)

MVP dagi yagona mas'uliyat printsipi MVC dan qattiqroq saqlanadi: View faqat renderlash uchun javobgar, Model — ma'lumotlar uchun, Presenter — mantiq va muvofiqlashtirish uchun. Haqiqiy loyihalarda Presenter ekran kodining 40–60% ini, View — 20–30% ini, Model — 20–30% ini tashkil qiladi. Bunday taqsimot Android emulyatori yoki iOS simulyatorini ishga tushirmasdan asosiy biznes mantiqni test qilish imkonini beradi.

MVP Android-da: Presenter, ViewContract va Activity

MVP Android-da Activity yoki Fragment ni ViewContract ni amalga oshiradigan View sifatida ishlatadi — ma'lumotlarni ko'rsatish metodlari bilan interfeys. Presenter Activity da yaratiladi, View ni o'ziga bog'laydi va yuklashni boshqaradi. Ekran aylantirilganda Activity qayta yaratiladi — Presenter retain-fragment yoki tashqi saqlash orqali saqlanishi mumkin, bu sof MVC ga xos bo'lgan holat yo'qotish muammosini hal qiladi.

kotlin
// ViewContract — Presenter ni View bilan bog'lash uchun interfeys
interface UserView {
    fun showLoading()
    fun hideLoading()
    fun showUser(user: User)
    fun showError(message: String)
}

// Presenter — test qilinadigan mantiq qatlami
class UserPresenter(
    private val repository: UserRepository
) {
    private var view: UserView? = null

    fun attachView(view: UserView) {
        this.view = view
    }

    fun detachView() {
        view = null
    }

    fun loadUser(userId: Int) {
        view?.showLoading()
        repository.getUser(userId) { result ->
            view?.hideLoading()
            result.onSuccess { user ->
                view?.showUser(user)
            }.onFailure { e ->
                view?.showError(e.message ?: "Noma'lum xato")
            }
        }
    }
}

// View (Activity) interfeysni amalga oshiradi
class UserActivity : AppCompatActivity(), UserView {
    private val presenter = UserPresenter(UserRepository())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        presenter.attachView(this)
        presenter.loadUser(42)
    }

    override fun onDestroy() {
        presenter.detachView()
        super.onDestroy()
    }

    override fun showUser(user: User) { /* UI ni yangilash */ }
    override fun showLoading() { /* ProgressBar ko'rsatish */ }
    override fun hideLoading() { /* ProgressBar yashirish */ }
    override fun showError(message: String) { /* Snackbar ko'rsatish */ }
}

Hayot aylanishini boshqarish — Android da MVP ning asosiy muammosi. Activity ekran aylantirilganda yo'q qilinadi va presenter.attachView() onCreate() da qayta chaqiriladi. Ma'lumot yuklashi asinxron bo'lsa (RxJava, korutinlar), tugallanish vaqtida View ajratilgan bo'lishi mumkin. Yechim — detachView() da obunalarni bekor qilish yoki Support Library dan Loader ishlatish (Jetpack bo'lmagan loyihalar uchun). IT Sectr da yillar davomida tijoriy loyihalarda MVP + RxJava kombinatsiyasini qo'lladik — namuna barqaror, lekin obunalarni boshqarishda intizom talab qiladi.

Retain-fragmentlar — ekran aylantirilganda Presenter ni saqlash mexanizmi. UI siz fragment (setRetainInstance(true)) Activity dan uzoqroq yashaydi va Presenter ga havolani saqlaydi. Activity qayta yaratilganda fragment bir xil Presenter ni yangi Activity ga uzatadi. Retain-fragmentlar AndroidX bilan eskirgan deb topilgan, ammo ularning pre-Jetpack analogi (Fragment.setRetainInstance) hali ham legacy loyihalarda ishlaydi. Zamonaviy ishlanmada Google retain-fragmentlar o'rniga ViewModel ni tavsiya qiladi.

MVP iOS-da: Presenter va View Protocol

MVP iOS-da View protokoli orqali quriladi. UIViewController protokolni amalga oshiradi, Presenter UIKit ni import qilmaydi va toza test qilinadi. Apple MVC dan farqli o'laroq, bunda UIViewController o'zi mantiq va to'g'ridan-to'g'ri IBOutlet bog'lanishlarini o'z ichiga oladi, Presenter holatni boshqaradi va View ga protokol metodlari orqali buyruq beradi. View qarorlar qabul qilmaydi — Presenter buyruqlarini bajaradi: showUser, showLoading, navigateToProfile.

swift
import Foundation

// View Protocol — Presenter uchun abstraksiya
protocol UserViewProtocol: AnyObject {
    func showLoading()
    func hideLoading()
    func display(user: User)
    func displayError(message: String)
}

// Presenter — toza mantiq, UIKit siz
final class UserPresenter {
    private weak var view: UserViewProtocol?
    private let service: UserServiceProtocol

    init(service: UserServiceProtocol) {
        self.service = service
    }

    func attach(view: UserViewProtocol) {
        self.view = view
    }

    func detach() {
        view = nil
    }

    func loadUser(id: Int) {
        view?.showLoading()
        service.fetchUser(id: id) { [weak self] result in
            guard let self else { return }
            self.view?.hideLoading()
            switch result {
            case .success(let user):
                self.view?.display(user: user)
            case .failure(let error):
                self.view?.displayError(message: error.localizedDescription)
            }
        }
    }
}

// View (UIViewController) protokolni amalga oshiradi
final class UserViewController: UIViewController, UserViewProtocol {
    private let presenter = UserPresenter(service: UserService())

    override func viewDidLoad() {
        super.viewDidLoad()
        presenter.attach(view: self)
        presenter.loadUser(id: 42)
    }

    func display(user: User) {
        nameLabel.text = user.name
    }
    // ... protokolning qolgan metodlari
}

Weak reference View ga — iOS MVP da majburiy shart. UIViewController yo'q qilinishi mumkin (navigatsiya stekidan pop), uning Presenter dagi closure i retain cycle yaratadi. Zaif havola (weak var) View ekrandan chiqqanda, Presenter da asinxron operatsiyalar mavjudligidan qat'i nazar, bo'shatilishini kafolatlaydi. Android da o'xshash muammo detachView() orqali hal qilinadi — onDestroy() dagi chaqiruv View ga havolani nolga tenglashtiradi.

Passive View vs Supervising Controller — Martin Faulerdan MVP ning ikki varianti. Passive View: View mantiqni o'z ichiga olmaydi, Presenter to'liq holatni boshqaradi. Supervising Controller: View o'zi oddiy ma'lumot bog'lashni amalga oshiradi (masalan, data binding orqali), Presenter faqat murakkab stsenariylarga aralashadi. Mobil ishlanmada Passive View ko'proq qo'llaniladi — maksimal test qilinish va ekran holatining bashorat qilinishini beradi.

MVP ni MVC dan farqlari va test afzalliklari

MVP va MVC o'rtasidagi asosiy farq — View bilan bog'lanish usuli. MVC da Controller View ga to'g'ridan-to'g'ri havolaga ega (UIViewController.IBOutlets, Activity.findViewById). MVP da Presenter ViewContract interfeysi orqali View bilan o'zaro aloqa qiladi. Bu farq test qilinishni tubdan o'zgartiradi: ViewContract ni amalga oshiradigan Mock ob'ekti Presenter mantiqini ilova, emulyator va UI freymvorkni ishga tushirmasdan tekshirish imkonini beradi.

MezonMVCMVP
View bilan bog'lanishTo'g'ridan-to'g'ri (Controller → View)Interfeys orqali (Presenter → ViewContract)
Mantiqni test qilishUIKit/Android Framework talab qiladiPlatforma bog'liqliklarisiz unit-testlar
Hayot aylanishiController ekran bilan yashaydiPresenter uzoqroq yashashi mumkin (retain)
MurakkablikMinimal+1 interfeys ekran boshiga
Massive ControllerOddiy muammoMantiq Presenter da, View yupqa

Presenter unit-test namunasi Kotlin da: mock UserView yaratiladi, Presenter ga uzatiladi, loadUser chaqiriladi, showUser to'g'ri ma'lumotlar bilan chaqirilganligi tekshiriladi. Test millisekundlarda bajariladi, emulyator talab qilmaydi. iOS da shunga o'xshash — OCMock yoki protokol-stab UserViewProtocol metod chaqiruvlarini tekshiradi. IT Sectr ning MVP bilan loyihalarida biznes mantiqning unit-testlar bilan qamrovi 85–90% ga yetdi, bu o'xshash MVC loyihalaridan 2–3 baravar yuqori.

MVP qachon MVC dan afzal — barqarorlikka qattiq talablar bilan loyihalarda: bank ilovalari, tibbiy tizimlar, to'lov terminallari. Bu sohalarda xato narxi yuqori va unit-testlar muhim ahamiyatga ega. Post-MVP loyihalarida (mahsulot bozorda, ammo kod bazasi legacy) MVP Massive View Controller dan mantiqni test qilinadigan qatlamga bosqichma-bosqich chiqarish imkonini beradi, arxitekturani to'liq qayta yozmasdan.

MVP ning cheklovlari va MVVM ga o'tish

MVP ning asosiy kamchiliklari — interfeyslar sonining ko'payishi va obunalarni qo'lda boshqarish. Har bir ekran kamida bitta ViewContract + Presenter talab qiladi, 50 ekran uchun — 50 interfeys va 50 Presenter sinfi. MVVM da ViewModel Presenter ni almashtiradi va reaktiv mexanizmlardan (LiveData, StateFlow, ObservableObject) foydalanadi, bu qo'lda attach/detach va ViewContract interfeyslariga ehtiyojni yo'q qiladi.

RxJava va MVP — Android 2015–2019 da mashhur kombinatsiya. Presenter Repository dan Observable ga obuna bo'ladi, natijani ViewContract orqali ko'rsatadi. Muammo: disposable detachView() da aniq bekor qilinishi kerak, aks holda obuna sizib chiqishi ajratilgan View ni yangilashda crash ga sabab bo'ladi. RxLifecycle va AutoDispose kutubxonalari qisman bekor qilishni avtomatlashtirdi, ammo bog'liqlik qo'shdi. IT Sectr da 2020 yilda MVP+RxJava dan MVVM+Flow ga o'tdik — kod ViewContract ning yo'qolishi hisobiga 25–30% qisqardi.

MVP dan MVVM ga migratsiya — bosqichma-bosqich jarayon. 1) Presenter da ViewContract ni LiveData/StateFlow bilan almashtirish. 2) attach/detach metodlarini olib tashlash — obuna observe() orqali amalga oshadi. 3) Presenter ni ViewModel deb nomlash. 4) ViewModelFactory uchun DI (Hilt/Koin) integratsiyasi. Bitta ekran migratsiyasi 2–4 soat, butun kod bazasi migratsiyasi — 50–100 ekranli loyiha uchun 2–4 hafta davom etadi. Migratsiyadan so'ng ViewContract interfeyslari olib tashlanadi, kod qisqaradi, testlar qoladi.

Zamonaviy ishlanmada MVP — namuna yashaydi, ammo MVVM va MVI dan ortda qoladi. Google rasman yangi loyihalar uchun MVVM ni Jetpack bilan tavsiya qiladi. Apple — MVVM ni SwiftUI bilan. Shunga qaramay, MVP ni bilish legacy kod bilan ishlash uchun majburiy: Google Play da yuzlab Android ilovalari, jumladan yirik banklar, chakana savdo tarmoqlari va transport kompaniyalarining ilovalari hali ham MVP da ishlaydi. MVP ni tushunish MVI va Clean Architecture ni o'zlashtirish uchun asosdir, chunki Presenter Robert Martin terminologiyasida Use Case ning to'g'ridan-to'g'ri ajdodidir.

Tez-tez beriladigan savollar

MVP MVC dan nima bilan farq qiladi?

MVP da Presenter View bilan ViewContract interfeysi orqali o'zaro aloqa qiladi, to'g'ridan-to'g'ri emas. MVC da Controller View ga to'g'ridan-to'g'ri havolaga ega (IBOutlet/findViewById). MVP Presenter ni unit-testlar bilan iOS Simulator yoki Android Emulator siz test qilish imkonini beradi, chunki Presenter UIKit yoki Android Framework ga bog'liq emas. MVC kontrollerni test qilish uchun ilovani ishga tushirishni talab qiladi.

Qachon MVP dan MVVM o'rniga foydalanish kerak?

MVP allaqachon shu namunada qurilgan legacy loyihalarda va reaktiv mexanizmlarni (LiveData, StateFlow, Combine) qo'llab-quvvatlamaydigan ilovalarda asoslanadi. Yangi loyihalar uchun Google MVVM ni Jetpack bilan (Android), Apple esa MVVM ni SwiftUI bilan (iOS) tavsiya qiladi. MVP Combine siz toza UIKit dagi loyihalar uchun biznes mantiqni unit-test qilish talabi bilan eng yaxshi tanlov bo'lib qolmoqda.

Ekran aylantirilganda Presenter yo'qolishi muammosini qanday hal qilish kerak?

Android da — retain-fragment (setRetainInstance(true)) yoki Jetpack dan ViewModel ishlatish. Retain-fragment Presenter ni aylantirishda saqlaydi va yangi Activity ga uzatadi. Google ning ViewModel i — retain-fragmentlarsiz aylantirishda holatni avtomatik saqlaydigan zamonaviy alternativa. iOS da — Presenter har viewDidLoad da qayta yaratiladi, lekin alohida koordinator xizmatida kesh saqlanadi.

MVP da bitta ekran uchun nechta sinf kerak?

Minimal 4: ViewContract interfeysi, ViewContract amalga oshirilishi (Activity/Fragment), Presenter, Model (Repository). Dagger/Hilt ishlatilsa, DI moduli qo'shiladi. 50 ekran uchun bu 200+ sinf. MVVM sonni ekran boshiga 1 faylga kamaytiradi (ViewContract kerak emas), MVI State va Intent sinflarini qo'shadi. Sinflar soni — katta loyihalarda MVP ga qarshi asosiy dalil.

Passive View va Supervising Controller o'rtasida MVP da qanday farq bor?

Passive View — View mantiqni o'z ichiga olmaydi, Presenter to'liq holat va ma'lumotlarni boshqaradi. Supervising Controller — View o'zi oddiy bog'lashni amalga oshiradi (data binding), Presenter murakkab stsenariylarga aralashadi. Mobil ishlanmada Passive View ustunlik qiladi — maksimal test qilinish va bashorat qilinishni beradi. Supervising Controller veb-freymvorklarda (ASP.NET Web Forms, GWT) qo'llaniladi.

Xulosa

  • MVP (Model-View-Presenter) — ViewContract interfeysi orqali test qilinadigan Presenter qatlami bilan MVC ning evolyutsiyasi
  • ViewContract — View ni Presenter dan abstraksiya qiladigan, mock testiga imkon beradigan interfeys
  • Passive View — passiv View bilan mobil ishlanmada dominant MVP varianti
  • Presenter — biznes mantiqni o'z ichiga oladi, UIKit yoki Android Framework ga bog'liq emas
  • MVP vs MVC — MVP test muammosini hal qiladi, lekin ekran boshiga 1 interfeys qo'shadi
  • Android retain-fragmentlar — Jetpack ViewModel paydo bo'lishidan oldin ekran aylantirishda Presenter ni saqlash
  • MVVM ga migratsiya — ViewContract ni LiveData/StateFlow bilan almashtirish kodni 25–30% qisqartiradi

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing