디자인 패턴 비교 (MVC, MVP, MVVM, MVI)
패턴 | View | 중간 계층 | Model | 데이터 흐름 | 특징 |
MVC | Activity/Fragement | Controller | 데이터 처리 | View와 Controller가 직접 연결됨 |
안드로이드에서는 유지보수 어려움 |
MVP | Activity/Fragement | Presenter | 데이터 처리 | View는 Presenter를 통해 데이터 요청 및 UI 업데이트 |
테스트 용이, 코드 분리 가능 |
MVVM | Activity/Fragement | ViewModel | 데이터 처리 | ViewModel이 데이터 변경을 감지하고 자동 업데이트 | LiveDate,StateFolw 활용 가능 |
MVI | Activity/Fragement | ViewModel + Reducer |
데이터 처리 | 단방향 데이터 흐름 (UI → Intent → State) |
UI 상태 관리가 강력함 |
1. MVC (Model-View-Controller)
초기 디자인 패턴으로 많이 사용되었지만, 안드로이드에서는 잘 사용되지 않음.
View와 Controller의 결합도가 높아서 유지보수가 어려운 단점이 있음.
- 구조
- Model: 데이터 및 비즈니스 로직 처리 (예: 데이터베이스, API)
- View: 사용자 인터페이스 (예: Activity, Fragment, XML)
- Controller: 사용자의 입력을 받아 Model을 업데이트하고 View를 갱신
- 데이터 흐름
- 사용자가 버튼을 클릭 → Controller가 이벤트 처리
- Controller가 Model에서 데이터를 가져옴
- Model이 데이터를 반환 → Controller가 View를 업데이트
- MVC 문제점
- View와 Controller의 강한 결합: 유지보수가 어려움
- Activity/Fragment가 Controller 역할을 하게 됨 → 코드가 복잡해짐
MVC 예제
class UserModel {
fun getUserName(): String {
return "고양이"
}
}
class MainActivity : AppCompatActivity() {
private val userModel = UserModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
textView.text = userModel.getUserName()
}
}
}
2. MVP (Model-View-Presenter)
MVC의 단점을 개선하여 Presenter를 도입한 패턴
- View와 Model을 완전히 분리하여 코드 유지보수성을 높임
- Presenter는 View와 Model의 중개 역할을 함
- View는 Presenter만 호출하며, Model에 직접 접근하지 않음
- 구조
- Model: 데이터 처리 (예: DB, API)
- View: UI 담당 (Activity, Fragment, XML)
- Presenter: 비즈니스 로직을 담당하고 View와 Model을 연결
- 데이터 흐름
- View가 Presenter에게 데이터 요청
- Presenter가 Model에서 데이터를 가져옴
- Presenter가 가공 후 View에 데이터 전달
MVP 예제
// Model
class UserModel {
fun getUserName(): String {
return "고양이"
}
}
// View (Interface)
interface MainView {
fun showUserName(name: String)
}
// Presenter
class MainPresenter(private val view: MainView) {
private val model = UserModel()
fun loadUser() {
val userName = model.getUserName()
view.showUserName(userName)
}
}
// View (Activity)
class MainActivity : AppCompatActivity(), MainView {
private lateinit var presenter: MainPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
presenter = MainPresenter(this)
button.setOnClickListener {
presenter.loadUser()
}
}
override fun showUserName(name: String) {
textView.text = name
}
}
3. MVVM (Model-View-ViewModel)
현재 안드로이드에서 가장 널리 사용되는 패턴
- ViewModel이 LiveData 또는 StateFlow를 사용하여 UI 업데이트
- View는 ViewModel만 관찰(Observe)하며, Model과 직접 연결되지 않음
MVVM 예제
class UserViewModel : ViewModel() {
private val _userName = MutableLiveData<String>()
val userName: LiveData<String> get() = _userName
fun loadUser() {
_userName.value = "고양이"
}
}
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: UserViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
viewModel.userName.observe(this) { name ->
textView.text = name
}
button.setOnClickListener {
viewModel.loadUser()
}
}
}
4. MVI (Model-View-Intent)
MVVM을 확장하여 단방향 데이터 흐름을 강조한 패턴
- View는 Intent를 ViewModel로 전달
- ViewModel은 상태(State)를 생성하여 View에 전달
- Redux 패턴과 유사하며, UI 상태 관리가 뛰어남
MVI 예제
sealed class MainIntent {
object LoadUser : MainIntent()
}
data class MainState(val userName: String = "")
class MainViewModel : ViewModel() {
private val _state = MutableLiveData<MainState>()
val state: LiveData<MainState> get() = _state
fun processIntent(intent: MainIntent) {
when (intent) {
is MainIntent.LoadUser -> _state.value = MainState(userName = "고양이")
}
}
}
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
viewModel.state.observe(this) { state ->
textView.text = state.userName
}
button.setOnClickListener {
viewModel.processIntent(MainIntent.LoadUser)
}
}
}
디자인 패턴 선택
상황 | 추천 패턴 |
간단한 앱 | MVVM (안드로이드 표준) |
대규모 프로젝트 | MVI (단방향 데이터 흐름) |
기존 코드가 MVC | MVP로 점진적 전환 |
'android studio' 카테고리의 다른 글
[Android] Checkbox 사용법 (Jetpack Compose) (0) | 2025.02.25 |
---|---|
[Android] TextField 사용법 (Jetpack Compose) (0) | 2025.02.24 |
[Android] MVVM (Model-View-ViewModel) 디자인 패턴 (0) | 2025.02.20 |
[Android] ViewModel 이란? (0) | 2025.02.19 |
[Android] remember / mutableStateOf 사용법 (Jetpack Compose) (0) | 2025.02.18 |