Blog
컴퓨터 공학
소프트웨어 아키텍쳐
MVC vs MVP vs MVVM

MVC vs MVP vs MVVM

MVC MVP MVVM

MVC(Model-View-Controller)

MVC 패턴에서는, Model은 데이터와 비즈니스 로직을, View는 사용자 인터페이스를, Controller는 Model과 View의 연결 역할을 담당합니다. MVC 패턴에서 View는 직접적으로 Model을 알 수 없으며, Model의 상태 변화를 Controller를 통해 간접적으로 알 수 있습니다.

MVP(Model-View-Presenter)

MVP 패턴은 MVC의 발전된 형태로 보는 경우가 많습니다. MVC 패턴에서는 Controller가 Model과 View 모두를 가지고 있지만, MVP에서는 Presenter가 Model과 View 인터페이스를 가지고 있습니다. 이로 인해, View와 Model 사이에 직접적인 연결이 없습니다. 이는 유닛 테스팅 등을 용이하게 합니다.

MVVM(Model-View-ViewModel)

MVVM 패턴에서는, Model은 데이터와 비즈니스 로직을, View는 사용자 인터페이스를, ViewModel은 View와 Model의 연결 역할을 담당합니다. View는 ViewModel에 바인딩되며, ViewModel은 Model의 데이터를 사용자에게 보여줄 수 있는 형태로 변환합니다. 이로써, ViewModel은 View를 위한 Model의 상태를 유지하게 됩니다.

MVVM vs MVC

MVVM은 View Model에서 데이터 바인딩을 통해서 View와 연결된다는 특징이 있다.
아래는 kotlin을 이용해서 Android Application을 작성하는 예제이다. 해당 코드를 보면 mvvm 패턴에서는 ViewModel이 LiveData를 사용하여 Model의 변경을 관찰하고 있다. 이것이 MVVM의 핵심 원칙 중 하나인 데이터 바인딩입니다.
이와 반대로 mvc 패턴에서는 view와 controller가 상호참조 하고 있는데 이는 다음과 같은 문제를 발생시키게 된다.

  1. 생명주기 관리 : Controller와 View가 서로 다른 생명주기를 가지고 있다면 복잡성이 증가하고 메모리 누수가 발생할 수 있다.
  2. 결합도 증가 : Controller와 View가 서로 참조하고 있다면 결합도가 증가해 사용성을 저하시키며 유지보수를 어렵게 만든다.
// Controller
class UserController(private val userView: UserView) {
    private val model = User("John Doe", 30)
 
    fun getUser() {
        // Update the view with model data
        userView.updateUserName(model.name)
        userView.updateUserAge(model.age)
    }
}
 
// Activity
class UserActivity : AppCompatActivity(), UserView {
 
    private lateinit var controller: UserController
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 
        controller = UserController(this)
 
        controller.getUser()
    }
 
    override fun updateUserName(name: String) {
        // Update UI
        nameTextView.text = name
    }
 
    override fun updateUserAge(age: Int) {
        // Update UI
        ageTextView.text = age.toString()
    }
}