소프트웨어 개발 방법론 (with MVVM)

kkosang·2025년 3월 30일
2
post-thumbnail

들어가며

서론

프로그래밍을 하다 보면 코드 구조를 어떻게 설계할지 고민하는 순간이 생깁니다.

프로젝트가 커지고 코드 라인이 증가할수록 유지보수와 확장성이 중요해지기 때문입니다. 이러한 문제를 해결하기 위한 방법으로 디자인 패턴아키텍처 패턴이 있습니다.

안드로이드 개발에서는 대표적으로 MVP, MVVM, MVI 같은 아키텍처 패턴이 주로 사용됩니다. 이 글에서는 먼저 디자인 패턴과 아키텍처 패턴의 차이를 이해하고, 가장 대중적이고 자주 사용되는 MVVM 패턴을 중심으로 다뤄보겠습니다.

디자인 패턴 vs 아키텍처 패턴

소프트웨어 개발에서는 코드의 유지보수와 확장성을 높이기 위해 다양한 설계 방식이 존재합니다. 대표적으로 디자인 패턴(Design Pattern)아키텍처 패턴(Architecture Pattern)이 있습니다.

디자인 패턴이란?

디자인 패턴(Design Pattern)은 소프트웨어 개발에서 반복적으로 일어나는 문제들을 해결하기 위한 코드 설계 방식입니다. 주로 클래스나 객체 간의 관계에 집중하며, 특정 상황에서 문제를 해결할 수 있도록 도와주는 코드구조입니다.

안드로이드 개발에서 자주 사용하는 디자인 패턴은 아래와 같습니다.

  • Singleton 패턴 : 단 하나의 인스턴스만 생성됨
  • Factory 패턴 : 객체 생성을 캡슐화하여 유연성을 제공
  • Observer 패턴 : 한 객체의 상태 변화가 다른 객체에 자동으로 전달됨

이외에도 다양한 디자인 패턴이 존재하며, GoF의 디자인 패턴을 참고하면 다양한 디자인 패턴에 대해서 알 수 있습니다.

아키텍처 패턴이란?

아키텍처 패턴(Architecture Pattern)은 애플리케이션 전체의 구조를 설계하는 방식입니다. 즉, 단순히 클래스간의 관계를 정의하는 것이 아니라, 전반적인 코드의 흐름과 역할을 분리하는 방법입니다.

안드로이드 개발에서 대표적으로 사용하는 아키텍처 패턴은 아래와 같습니다.

  • MVC 패턴 : View와 Model을 연결하는 Controller가 존재하는 구조
  • MVP 패턴 : Presenter가 View와 Model 사이에서 중개하는 구조
  • MVVM 패턴 : ViewModel을 통해 데이터와 UI를 분리하는 구조
  • MVI 패턴 : 상태를 기반으로 UI를 갱신하는 구조

MVC 패턴은 안드로이드에서 View와 Controller의 경계가 모호하여 잘 사용하지 않는 패턴입니다.

아키텍처 패턴은 애플리케이션의 코드 구조를 조직화하고 역할을 분리하여 유지보수를 쉽게하는 것이 목표입니다.

디자인 패턴 vs 아키텍처 패턴

비교 항목디자인 패턴아키텍처 패턴
목적특정 문제를 해결하기 위한 코드 설계애플리케이션 전체의 구조를 설계
범위클래스, 객체애플리케이션 전체
예시Singleton, Factory, ObserverMVC,MVP,MVVM,MVI

디자인 패턴과 아키텍처 패턴을 사용하는 목적은 비슷하지만 서로 독립적인 개념입니다. 디자인 패턴과 아키텍처 패턴은 적용하는 범위가 다르기 때문에 어느 하나만을 선택하는 것이 아닌 함께 사용될 수 있습니다. 예를 들어 MVVM 패턴을 적용하면서 Singleton 같은 디자인 패턴을 함께 사용하는 것이 가능합니다.

즉, 아키텍처 패턴은 애플리케이션의 큰 그림을 그리는 역할을 하고, 디자인 패턴은 세부적으로 특정 기능을 구현하는 도구로 사용할 수 있습니다.

MVVM 패턴이란?

아키텍처 패턴 중 하나인 MVVM(Model-View-ViewModel) 패턴은 UI와 비즈니스 로직을 분리하여 유지보수성을 높이고 단방향 데이터 (UDF) 흐름을 유지하는 아키텍처 패턴입니다.

MVVM 구성 요소

MVVM 패턴의 구성 요소는 아래와 같이 크게 3가지로 구성됩니다.

  • Model
    • 애플리케이션의 데이터와 비즈니스 로직을 관리
    • UI에 대한 정보를 알지 못함
  • View
    • 사용자 인터페이스(UI)를 담당
    • ViewModel과 상호작용하며 데이터 바인딩을 활용해 UI 갱신
  • ViewModel
    • View와 Model을 연결하는 중개자 역할
    • Model의 데이터를 가공하고 View와 직접 연결되지 않음
    • LiveData, StateFlow 와 같은 Observable 데이터를 활용하여 UI 업데이트 지원

MVVM 패턴의 장점

MVVM 패턴은 UI와 비즈니스 로직을 분리할 수 있기 때문에, 유지보수에 용이하고 테스트 하기도 쉬워진다는 장점이 있습니다.

UI와 비즈니스 로직의 분리

  • UI의 렌더링은 View에서만 담당하고 비즈니스 로직 ViewModel에서 처리하여 분리할 수 있음
  • LiveData, StateFlow 등을 활용하여 ViewModel의 상태를 자동으로 UI에 반영

✅ 테스트 용이성

  • ViewModel은 UI에 대한 직접적인 참조가 없기 때문에 단위 테스트 (Unit Test) 용이

✅ 생명주기 고려

  • ViewModel의 생명주기는 Activity와 Fragment의 생명주기와 별개로 유지
  • 화면 회전 시에도 ViewModel의 인스턴스가 유지되어 데이터 손실 방지

MVVM 패턴의 동작 방식

앞서, MVVM 패턴이 무엇이며 어떠한 장점을 가질 수 있는지 알아보았습니다.

그렇다면 MVVM 패턴은 어떤 방식으로 동작하기에 UI와 비즈니스 로직을 분리할 수 있을까요?

바로 단방향 데이터 흐름데이터 바인딩 기법을 사용하여 UI와 로직을 명확히 분리할 수 있기 때문입니다.

이제 MVVM의 데이터 흐름을 이해하고, LiveData, StateFlow 같은 데이터 바인딩 기법이 어떻게 활용되는지 살펴보겠습니다.

View ↔ ViewModel ↔ Model 흐름

MVVM 패턴은 단방향 데이터 흐름을 따릅니다.

이를 아래와 같은 그림처럼 나타낼 수 있습니다.

MVVM

  1. 사용자 이벤트 발생 (View → ViewModel)
    • View ( Activity/Fragment/Composable )가 UI 이벤트를 감지하고 해당 이벤트를 ViewModel 에게 전달
  2. 데이터 요청 및 처리 (ViewModel → Model)
    • ViewModel이 Model에게 데이터를 요청
    • Model에서 데이터를 가져와서 ViewModel에서 가공
  3. 데이터 전달 및 UI 업데이트 (ViewModel → View)
    • ViewModel이 데이터를 View에게 전달함, 이때 직접적으로 전달하는 것이 아닌 데이터 바인딩 기법 적용
    • View는 데이터를 관찰(Observe)하며 UI를 업데이트 함

이러한 방식으로 데이터가 한 방향으로 흐르는 방법을 사용하여 MVVM 패턴 적용

데이터 바인딩 기법

MVVM 패턴에서는 UI와 데이터를 동기화하기 위해 LiveData와 StateFlow 같은 Observable 데이터 타입을 활용합니다.

Observable 데이터 타입이란?

Observable 데이터 타입은 데이터가 변경될 때, 이를 자동으로 감지하여 알림을 보내는 데이터 객체를 의미합니다. 이러한 개념은 디자인 패턴 중 옵저버 패턴에서 비롯되었으며 대표적으로 LiveData, StateFlow 등이 있습니다.

MVVM에서 ViewModel이 데이터를 관리하고, UI(View)는 이를 관찰(Observe)하여 변경 사항을 자동으로 반영할 수 있습니다.

대표적인 Observable 데이터 타입으로 LiveData 가 있으며, 옵저버 패턴의 개념을 적용하여 동작합니다.

LiveData란?

  • 생명주기를 인식하는 Observable한 데이터 객체
  • Activity, Fragment 등 생명주기를 고려

다음은 사용자의 이름 데이터를 텍스트관리하는 UserViewModel의 간단한 예시입니다.

class UserViewModel : ViewModel() {

		private val _name = MutableLiveData<String>()
		val name : LiveData<String> get() = _name
		
		// View에서 name을 변경하라는 이벤트 전달
		fun updateName(newName: String){
			_name.value = newName // 데이터 변경 
		}
}

// Activity
viewModel.name.observe(this) { newName ->
    textView.text = newName  // UI 자동 업데이트
}

UserViewModel의 name 프로퍼티를 LiveData로 선언하여 데이터의 값을 관찰할 수 있습니다. 즉, name의 데이터를 관찰하고 값이 변경되면 UI를 변경하도록 하여 MVVM 패턴을 구현할 수 있습니다.

마치며

아키텍처 패턴과 디자인 패턴에 대해서 간략하게 알아봤습니다. 아키텍처 패턴은 애플리케이션의 전반적인 구조를 개선하고 유지보수 및 확장성을 높이는 데 도움을 줄 수 있습니다. 디자인 패턴은 구현 과정에서 발생하는 다양한 문제를 해결하는 도구입니다. 아키텍처 패턴과 디자인 패턴은 배타적으로 사용하는 것이 아닌, 서로 상호보완하며 활용될 수 있습니다. 아키텍처 패턴인 MVVM을 구현하기 위해 아키텍처 패턴인 옵저버 패턴을 사용하는 것처럼, 함께 사용할 수 있습니다. 마지막으로 패턴은 어디까지나 도구일 뿐, 무작정 도입하기 보다는 각 프로젝트의 필요성에 맞게 이유와 목적을 가지고 도입하는 것이 중요합니다.

출처

https://www.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS8616098823

0개의 댓글