728x90
반응형
디자인 패턴은 개발 및 유지보수를 좀더 체계적이고, 효율적으로 하기 위한 방법론이다.
그 중에서도 MVC 패턴이 굉장히 유명한데, UI와 비즈니스 로직을 분리하기 위해 만들어진 패턴이다.
그러나 이 패턴에도 문제점이 있었고, 그걸 해결하기 위해 MVP를 거쳐 현재는 MVVM으로 파생되었다.
각각이 장단점이 있어 맞는 방법론을 찾아 사용하는 것이 좋다.
현재 android 앱개발 쪽에서는 MVVM을 선호하는데, 흐름을 보면 그 이유를 알 수 있다.
MVC 패턴
- Model + View + Controller 로 역할을 나누어 코드를 관리하는 패턴
- 목적 : UI와 데이터/비즈니스 로직을 분리하여 개발, 테스트 및 유지보수를 쉽게 하는 것
- 구조
- Model : 데이터 처리
- View : UI
- Controller : 사용자의 입력을 처리, model과 view를 중간에서 제어
- 예시 코드 - user 정보를 저장하고 관리
- model
- user 클래스를 통해 데이터를 저장, 관리하는 역할
- model
data class User(val name: String, val age: Int)
-
- view
- 사용자에 데이터를 보여주는 역할
- view
class UserView {
fun displayUserDetails(name: String, age: Int) {
println("User Name: $name, Age: $age")
}
}
-
- controller
- 데이터를 갱신하는 등 비즈니스 로직이 들어가는 부분
- 데이터 갱신 시 model에 직접 접근하고, view에도 직접 접근해 보여주는 방식
- controller
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가 완전히 분리됨
- data binding 과정이 있어 property 값이 변경될 때 변경 전 값과 변경 후 값을 알리는 callback 존재
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 |