CS/Android

MVC 패턴 vs MVP 패턴 vs MVVM 패턴

졔졔311 2024. 12. 13. 16:33
728x90
반응형

디자인 패턴은 개발 및 유지보수를 좀더 체계적이고, 효율적으로 하기 위한 방법론이다.

그 중에서도 MVC 패턴이 굉장히 유명한데, UI와 비즈니스 로직을 분리하기 위해 만들어진 패턴이다.

그러나 이 패턴에도 문제점이 있었고, 그걸 해결하기 위해 MVP를 거쳐 현재는 MVVM으로 파생되었다.

각각이 장단점이 있어 맞는 방법론을 찾아 사용하는 것이 좋다.

현재 android 앱개발 쪽에서는 MVVM을 선호하는데, 흐름을 보면 그 이유를 알 수 있다.


MVC 패턴

  • Model + View + Controller 로 역할을 나누어 코드를 관리하는 패턴
  • 목적 : UI와 데이터/비즈니스 로직을 분리하여 개발, 테스트 및 유지보수를 쉽게 하는 것
  • 구조
    • Model : 데이터 처리
    • View : UI
    • Controller : 사용자의 입력을 처리, model과 view를 중간에서 제어
  • 예시 코드 - user 정보를 저장하고 관리
    • model
      • user 클래스를 통해 데이터를 저장, 관리하는 역할
data class User(val name: String, val age: Int)
    • view
      • 사용자에 데이터를 보여주는 역할
class UserView {
    fun displayUserDetails(name: String, age: Int) {
        println("User Name: $name, Age: $age")
    }
}
    • controller
      • 데이터를 갱신하는 등 비즈니스 로직이 들어가는 부분
      • 데이터 갱신 시 model에 직접 접근하고, view에도 직접 접근해 보여주는 방식
class UserController(private val model: User, private val view: UserView) {
    fun updateUserName(newName: String) {
        model.copy(name = newName) // 데이터 갱신
    }
 
    fun updateUserAge(newAge: Int) {
        model.copy(age = newAge) // 데이터 갱신
    }
 
    fun showUserDetails() {
        view.displayUserDetails(model.name, model.age)
    }
}

 

  • 문제점
    • view와 model 사이의 의존성이 낮아졌지만, 그럼에도 완전히 분리 x ->  앱이 커질수록 복잡하고 유지보수 어려움
    • 앱이 확장될수록 view가 많아져 controller가 과도하게 커질 수 있음

MVP 패턴

  • controller 대신 presenter가 존재하는 패턴 => Model + View + Presenter
  • view에서 직접 사용자의 요청을 받음
  • 목적 : view와 model 사이에 presenter를 두어 제어하므로, 의존성이 낮아져 테스트가 용이
  • 구조
    • Model : 데이터 처리
    • View : UI. 여기서 요청을 받아 처리
    • Presenter : model과 view를 중간에서 제어
  • 문제점
    • view와 presenter 사이의 의존성이 강하므로 앱이 커질수록 의존성이 강화되는 형태
    • view와 presenter는 1:1 관계를 가지고, view가 증가할수록 presenter의 개수도 증가하기 때문에 코드도 함께 증가해 복잡도가 올라갈 수 있음

MVVM 패턴

  • Model+View+ViewModel로 역할을 나누어 관리하는 패턴. 기존 presenter가 viewmodel로 대체됨
  • 목적 : MVP에서 남아있던 model과 view 사이의 의존성을 완전히 없애 UI와 비즈니스 로직을 완전히 분리
  • ViewModel은 하나만 있고, 여러개의  View와 연결된 구조
  • view에서 필요한 데이터의 형태대로 view model에서 가공/저장하고, view에서는 이걸 보여주기만 함
  • view에서는 이벤트를 view model로 전달하고, data binding을 통해 view model에서 수정된 데이터를 보여줌
    ( = view를 참조 x )
  • 구조
    • Model : 데이터 처리
    • View : UI, 사용자의 입력을 처리
    • View Model : view를 위한 데이터 처리. UI 관련 데이터를 저장하고 관리하는 역할. view를 참조하지 x
  • 예시 코드
    • model : 기존과 동일 
data class User(var name: String, var age: Int)
  • view : 기존과 동일
class UserView {
    fun displayUserDetails(name: String, age: Int) {
        println("User Name: $name, Age: $age")
    }
}
  • viewmodel
    • data binding 과정이 있어 property 값이 변경될 때 변경 전 값과 변경 후 값을 알리는 callback 존재
      -> 즉, 값이 변경되면 자동으로 해당 메소드 수행
      (여기서는 Delegates 객체의 observable 메서드를 사용)
    • view에 접근하지 않아 UI가 완전히 분리됨
import kotlin.properties.Delegates
 
class UserViewModel(private val user: User) {
    // Data Binding (Observable). 위임 property "by"와 함께 사용
    var name: String by Delegates.observable(user.name) { _, _, newValue ->
        user.name = newValue
    }
    var age: Int by Delegates.observable(user.age) { _, _, newValue ->
        user.age = newValue
    }
 
    // Method to get updated data
    fun getUser(): User {
        return user
    }
}
  •  문제점
    • view model의 설계가 어려움
    • 빌드 속도 저하
728x90
반응형

'CS > Android' 카테고리의 다른 글

공통 객체 이용하기 - CompositionLocal  (0) 2024.12.17
Navigation  (0) 2024.12.16
Composable & Preview  (0) 2024.12.13
Ktlint vs Detekt vs Android Lint  (1) 2024.12.13
DATA BINDING  (0) 2024.12.13