MVC (Model-View-Controller) — isang pattern ng arkitektura na naghahati ng aplikasyon sa tatlong bahagi: Model ang responsable para sa datos at lohika ng negosyo, View — para sa interface ng gumagamit, Controller — para sa pagproseso ng input at koordinasyon ng Model at View. Sa iOS, ang MVC ay ipinatutupad sa pamamagitan ng UIViewController, sa Android — sa pamamagitan ng Activity at Fragment. Ang MVC ay nananatiling pangunahing pattern kung saan itinayo ang MVVM, MVP at Clean Architecture. Higit pa — sa MVC in Cocoa Core.
Mga Pangunahing Punto
MVC (Model-View-Controller) — isang pattern ng arkitektura na iminungkahi ni Trygve Reenskaug noong 1979 para sa wikang Smalltalk-80. Hinahati ng pattern ang aplikasyon sa tatlong layer: Naglalaman ang Model ng datos at lohika ng negosyo, Ang View ay responsable para sa pagpapakita, Pinoproseso ng Controller ang input ng gumagamit at ina-update ang Model at View. Ang paghihiwalay ng responsibilidad ay nagpapahintulot sa pagbabago ng bawat layer nang nakapag-iisa — halimbawa, pagpapalit ng View mula UIKit patungong SwiftUI nang hindi binabago ang lohika ng negosyo sa Model.
Interaksyon ng mga bahagi sa MVC ay sumusunod sa isang cycle: ang gumagamit ay nakikipag-ugnayan sa View → Natatanggap ng Controller ang kaganapan → Ina-update ng Controller ang Model → Ipinapaalam ng Model sa Controller ang mga pagbabago → Ina-update ng Controller ang View. Sa klasikong pagpapatupad, ang Model ay gumagamit ng Observer pattern: sa pagbabago ng datos, ang Model ay nagpapadala ng mga abiso, ang Controller ay nag-subscribe at ina-update ang View. Sa pagpapatupad ng Apple, ang Key-Value Observing (KVO) o NotificationCenter ay gumaganap ng papel na ito.
| Bahagi | Responsibilidad | Halimbawa sa iOS | Halimbawa sa Android |
|---|---|---|---|
| Model | Datos, lohika ng negosyo, network | Struct User, CoreData | Data class, Repository |
| View | Pagpapakita ng UI | Storyboard, XIB, UIView | XML layout, Jetpack Compose |
| Controller | Pagproseso ng input, koordinasyon | UIViewController | Activity, Fragment |
MVC sa modernong pag-develop ng mobile ay mas madalas gamitin kaysa 10 taon nakaraan, ngunit nananatiling sapilitan para maintindihan. Inirerekomenda ng Apple ang MVC para sa mga simpleng screen sa UIKit aplikasyon. Hindi inirerekomenda ng Google ang purong MVC para sa Android — ang opisyal na dokumentasyon ay nagmumungkahi ng MVVM sa Jetpack. Gayunpaman, ang kaalaman sa MVC ay kinakailangan para sa pagtatrabaho sa mga legacy na proyekto at para sa pag-unawa sa ebolusyon ng mga pattern ng arkitektura.
Apple MVC — isang pasadyang pagpapatupad ng pattern na naka-embed sa UIKit. Ang UIViewController ay gumaganap bilang Controller: namamahala sa siklo ng buhay ng screen (viewDidLoad, viewWillAppear, viewDidDisappear), pinoproseso ang mga pagpindot at aksyon ng gumagamit, ina-update ang View sa pamamagitan ng IBOutlets. Ang View ay ginagawa sa Interface Builder (storyboard o XIB) o programmatically. Model — anumang mga bagay ng datos: mga serbisyo sa network, CoreData stack, mga istraktura ng Swift.
final class UserViewController: UIViewController {
// View (sa pamamagitan ng storyboard outlet)
@IBOutlet private var nameLabel: UILabel!
@IBOutlet private var emailLabel: UILabel!
// Model
private let userService = UserService()
override func viewDidLoad() {
super.viewDidLoad()
loadUser()
}
private func loadUser() {
userService.fetchUser { [weak self] user in
// Ina-update ng Controller ang View
self?.nameLabel.text = user.name
self?.emailLabel.text = user.email
}
}
}
Problema ng Apple MVC — ang View at Controller ay mahigpit na nakatali. Ang UIViewController ay sabay na namamahala sa View at lohika. Ang Storyboard ay nag-iimbak ng View sa XML, ngunit ang controller ay may direktang mga sanggunian sa mga elemento ng UI sa pamamagitan ng IBOutlets. Nilalabag nito ang prinsipyo ng nag-iisang responsibilidad: ang controller ay responsable para sa siklo ng buhay, mga delegado, datasource, target-action at mga animasyon. Bilang resulta, ang isang karaniwang screen ng iOS aplikasyon ay naglalaman ng 200–500 linya sa controller.
Siklo ng buhay ng ViewController — Nagbibigay ang Apple ng 6 na pamamaraan ng siklo ng buhay: loadView (manu-manong paggawa ng View), viewDidLoad (pagkatapos ma-load ang View sa memorya), viewWillAppear (bago lumitaw sa screen), viewDidAppear (pagkatapos ng animasyon), viewWillDisappear (bago umalis sa screen), viewDidDisappear (pagkatapos umalis). Bawat pamamaraan — isang lugar para ilagay ang lohika sa MVC. Ang paggamit ng mga pamamaraang ito para sa lohika ng negosyo ay nagpapabilis sa paglaki ng controller.
Android MVC — Ang Activity at Fragment ay gumaganap bilang Controller, ang mga XML layout file — View, anumang POJO klase na may datos — Model. Ang Activity ay namamahala sa siklo ng buhay ng screen: onCreate, onStart, onResume, onPause, onStop, onDestroy. Fragment — sub-screen sa loob ng Activity na may sariling siklo ng buhay. Ang View (XML) ay hiwalay sa Controller at na-load sa pamamagitan ng setContentView o LayoutInflater. Model — mga repositoryo, mga database, mga tawag sa network.
class UserActivity : AppCompatActivity() {
// View sa pamamagitan ng XML layout
private lateinit var binding: ActivityUserBinding
// Model
private val userRepository = UserRepository()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityUserBinding.inflate(layoutInflater)
setContentView(binding.root)
loadUser()
}
private fun loadUser() {
userRepository.getUser { user ->
runOnUiThread {
binding.nameText.text = user.name
binding.emailText.text = user.email
}
}
}
}
Android ViewBinding at DataBinding — mga modernong kasangkapan na nagbabawas ng pagkakatali ng Controller at View. Ang ViewBinding ay lumilikha ng isang klase na may direktang sanggunian sa View mula sa XML, tinatanggal ang findViewById. Ang DataBinding ay nagdaragdag ng kakayahang mag-ugnay ng datos sa UI sa XML markup sa pamamagitan ng @{user.name}. Ang DataBinding — isang hakbang patungo sa MVVM, dahil pinapayagan nito ang paglipat ng datos mula sa Model patungo sa View nang walang code sa Activity. Inirerekomenda ng Google ang DataBinding para sa lahat ng bagong proyekto.
Siklo ng buhay ng Android ay mas kumplikado kaysa sa iOS: ang Activity ay maaaring masira at muling likhain sa pag-ikot ng screen, kakulangan ng memorya o pagbabago ng configuration. Sa purong MVC, ang controller (Activity) ay naglalaman ng lohika na nawawala kapag nasira. Nangangailangan ito ng pag-save ng estado sa pamamagitan ng onSaveInstanceState o ViewModel mula sa Jetpack, na lumalampas sa balangkas ng purong MVC at naglalapit ng arkitektura sa MVVM.
Massive View Controller — terminong naglalarawan sa pangunahing problema ng MVC sa pag-develop ng mobile. Ang controller sa iOS at Android ay kumukuha ng masyadong maraming responsibilidad: pagproseso ng input, pag-validate ng datos, interaksyon sa network, nabigasyon, caching, animasyon, pamamahala ng siklo ng buhay. Bilang resulta, ang controller ay lumalaki hanggang 500–2000 linya ng code, nagiging mahirap basahin, subukan at panatilihin.
Mga sanhi ng Massive View Controller — ang arkitektura ng UIKit at Android Framework ay naghihikayat sa paglalagay ng lohika sa controller. Ang mga tawag sa network, pagproseso ng JSON, nabigasyon — lahat ng ito ay natural na isinusulat sa Activity o UIViewController, dahil may access sila sa siklo ng buhay at UI. Ang developer ay dapat sinasadya na ilipat ang lohika sa magkakahiwalay na klase (Service, Manager, Interactor), na nangangailangan ng disiplina at pag-unawa sa mga prinsipyo ng arkitektura.
| Problema ng MVC | Paglalarawan | Solusyon |
|---|---|---|
| Mahigpit na pagkakatali | Alam ng Controller ang View at Model | MVVM — Hindi alam ng ViewModel ang View |
| Hirap subukan | Ang Controller ay nakadepende sa UIKit/Android | Paglipat ng lohika sa mga serbisyo |
| Siklo ng buhay | Nawawala ang estado sa pag-ikot | ViewModel mula sa Jetpack/SwiftUI |
| Kawalan ng nabigasyon | Namamahala ang Controller ng mga transisyon | Pattern ng Coordinator, Router |
Pagsubok ng MVC — Ang Model ay sinusubok nang nakahiwalay sa mga unit test. Ang Controller ay mahirap subukan dahil sa pagdepende sa UIKit/UIFoundation. Hindi pinapayagan ng XCTest ang paggawa ng UIViewController nang walang window ng view. Para sa Android, ang ActivityTestRule at Robolectric ay bahagyang lumulutas sa problema, ngunit ang mga test ay mabagal. Ang View ay karaniwang hindi sinusubok sa mga unit test — para sa UI ay ginagamit ang mga screenshot at UI test (XCUITest, Espresso).
Kailan nabibigyang-katwiran ang MVC — mga simpleng screen na may isa-dalawang elemento (screen ng pag-login, profile, mga setting). Mga prototype at MVP para sa pagsubok ng mga hipotesis — ang MVC ay mas mabilis isulat nang walang karagdagang mga layer. Mga proyektong may maliit na base ng code hanggang 10–15 screen. Sa mga kumplikadong proyekto, ang MVC ay humahantong sa akumulasyon ng teknikal na utang at nangangailangan ng refactoring bawat 6–12 buwan.
MVC vs MVVM — pangunahing pagkakaiba: sa MVVM ang controller ay pinalitan ng ViewModel na walang sanggunian sa View. Ang datos ay inililipat sa pamamagitan ng Observable (SwiftUI), LiveData/StateFlow (Android) o Combine/RxSwift. Ang ViewModel ay sinusubok sa mga unit test nang walang mga dependensya sa UI. Inirerekomenda ng Apple ang MVVM sa SwiftUI mula noong 2019, Google — MVVM sa LiveData/Flow bilang opisyal na arkitektura ng Android. Ang MVVM ay nangangailangan ng mas maraming code para sa pag-ugnay, ngunit makabuluhang pinapabuti ang testability.
MVC vs MVP — sa MVP (Model-View-Presenter) ang Presenter ay isang testable na layer na tumatanggap ng View sa pamamagitan ng interface. Hindi tulad ng MVC, kung saan ang Controller ay direktang namamahala sa View sa pamamagitan ng UIKit, ang Presenter ay hindi nakadepende sa framework — gumagana ito sa pamamagitan ng abstraksyon ng ViewInterface. Ang MVP ay popular sa pag-develop ng Android bago ang pagdating ng Jetpack at ginagamit sa mga lumang proyekto. Ang Presenter ay nabubuhay nang mas mahaba kaysa sa Activity at pinapanatili ang estado sa pag-ikot ng screen.
MVC vs Clean Architecture — Ang Clean Architecture ay nagdaragdag ng mga layer ng Use Cases (Interactors), Entities, Gateways at Repository. Ang MVC ay nananatili sa Presentation layer, ngunit ang lohika ng negosyo ay inililipat sa Domain layer na may Use Cases. Ang Clean Architecture ay lumulutas sa problema ng Massive View Controller nang radikal — ang Controller ay naglalaman lamang ng mga tawag sa Use Cases at pag-update ng View. Ang kahinaan ay ang makabuluhang pagtaas ng bilang ng mga klase at file, na nabibigyang-katwiran para sa mga proyektong may 50+ screen.
// MVC sa iOS: Naglalaman ang Controller ng lahat
class OrderViewController: UIViewController {
func placeOrder() {
// Pag-validate + network + UI update
guard Validation.isValid(total) else { return }
NetworkService.shared.submit(order) { [weak self] result in
self?.handleResult(result)
}
}
}
// MVVM: lohika sa ViewModel
class OrderViewModel: ObservableObject {
@Published var state: OrderState = .idle
func placeOrder() { /* business logic */ }
}
Pagpili ng arkitektura ay nakadepende sa laki ng koponan, proyekto at kinakailangang testability. Para sa isang koponan ng 1–2 developer at proyekto hanggang 20 screen, ang MVVM ay angkop. Para sa malaking koponan mula 5 developer at proyekto mula 50 screen — Clean Architecture na may modular na istraktura. Ang MVC ay nananatiling nauugnay para sa pag-unawa sa ebolusyon ng mga arkitektura, para sa suporta ng mga legacy na proyekto at para sa mga simpleng screen sa UIKit na walang kumplikadong lohika ng negosyo.
Mga Madalas Itanong
Ang pangunahing problema ay ang Massive View Controller. Sa iOS, ang controller na UIViewController ay responsable para sa lahat: pagproseso ng input, pag-update ng View, pagtatrabaho sa network, nabigasyon at siklo ng buhay. Sa Android, ang Activity/Fragment ay gumaganap ng mga katulad na function. Bilang resulta, ang controller ay lumalaki hanggang libu-libong linya ng code, nagiging mahirap subukan at panatilihin, lumalabag sa prinsipyo ng nag-iisang responsibilidad.
Sa MVC, ang controller ay direktang nag-a-update ng View at pinoproseso ang input ng gumagamit. Sa MVVM, ang papel ng controller ay ginagampanan ng ViewModel na walang sanggunian sa View — ang datos ay inililipat sa pamamagitan ng mga mekanismo ng pag-ugnay. Ang MVVM ay mas mahusay na sinusubok dahil ang ViewModel ay hindi nakadepende sa UIKit o Android Framework. Inirerekomenda ng Apple ang MVVM sa SwiftUI, Google — MVVM sa Jetpack Compose.
Oo, ang MVC ay nananatiling isang gumaganang pattern para sa mga simpleng screen at prototype. Inirerekomenda ng Apple ang MVC para sa UIKit aplikasyon na may mga simpleng screen. Para sa mga kumplikadong proyekto na may maraming screen, mga kahilingan sa network at caching, mas mainam na pumili ng MVVM, VIPER o Clean Architecture. Ang mga baguhang developer ay pinapayuhan na makabisado ang MVC bago mag-aral ng mas kumplikadong mga pattern.
Ang Model ay sinusubok nang nakahiwalay — ito ay mga ordinaryong bagay ng datos at lohika ng negosyo. Ang Controller ay mahirap subukan dahil sa pagdepende sa UIKit o Android Framework. Inirerekomenda na ilipat ang lohika ng negosyo mula sa controller patungo sa magkakahiwalay na serbisyo o interaktor, na sinusubok sa mga unit test. Ang View ay karaniwang hindi sinusubok sa mga unit test — para dito ginagamit ang mga UI test at screenshot test.
Sa iOS — MVVM sa SwiftUI at Combine, pamantayan ng Apple mula noong 2019. Sa Android — MVVM sa LiveData o StateFlow, opisyal na inirerekomenda ng Google. Para sa malalaking proyekto na may mga koponan mula 5 developer — Clean Architecture na may VIPER sa iOS o Clean Architecture sa Android na may paghahati sa mga module ayon sa feature. Para sa mga legacy na proyekto na may MVC — unti-unting refactoring na may paglipat ng lohika sa magkahiwalay na serbisyo.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din