Design Pattern

MVVM (Model-View-ViewModel) 패턴

Russell Developer 2024. 10. 14. 05:15

MVVM (Model-View-ViewModel) 패턴 - 구조와 활용

MVVM 패턴(Model-View-ViewModel)은 WPF, Xamarin, Unity 등에서 자주 사용되는 아키텍처 패턴으로, UI 코드와 비즈니스 로직을 분리하여 효율적인 유지보수와 확장성을 제공합니다. MVVM은 특히 데이터 바인딩을 지원하는 프레임워크에서 널리 사용되며, 프론트엔드와 백엔드 간의 명확한 역할 분리를 통해 생산성을 높입니다.


1. MVVM 패턴이란?

MVVM 패턴은 애플리케이션을 세 가지 주요 구성 요소로 분리합니다:

  1. Model(모델): 데이터와 비즈니스 로직을 관리하는 부분입니다. Model은 데이터를 저장하고 처리하며, ViewModel에 데이터를 전달하는 역할을 합니다.
  2. View(뷰): 사용자에게 데이터를 보여주는 화면을 처리하는 부분입니다. View는 UI 요소들로 구성되며, ViewModel에 의해 전달된 데이터를 표시합니다.
  3. ViewModel(뷰모델): View와 Model 사이에서 중개 역할을 하는 부분입니다. ViewModel은 Model에서 데이터를 받아 View에 전달하고, View에서 발생한 이벤트를 처리하여 Model에 반영합니다. 양방향 데이터 바인딩을 통해 View와 ViewModel이 연결됩니다.

2. MVVM 패턴의 동작 흐름

MVVM 패턴의 기본 동작은 다음과 같습니다:

  1. 사용자 입력: 사용자가 UI 상에서 버튼 클릭이나 입력을 통해 상호작용을 합니다.
  2. ViewModel 처리: ViewModel이 사용자의 요청을 받아서 처리합니다. ViewModel은 데이터를 Model에 요청하거나, Model의 데이터를 업데이트합니다.
  3. Model 업데이트: ViewModel의 요청에 따라 Model이 데이터를 변경하거나 조회한 후, ViewModel로 데이터를 반환합니다.
  4. View 업데이트: ViewModel에서 처리된 데이터를 기반으로 View가 자동으로 업데이트됩니다. 이 과정은 주로 데이터 바인딩을 통해 자동으로 이루어집니다.

3. MVM 패턴의 장점

  1. 유지보수성 향상: UI와 비즈니스 로직이 ViewModel을 통해 분리되어 있어, UI 변경 없이 비즈니스 로직을 수정할 수 있고, 반대로 UI를 변경할 때도 비즈니스 로직에 영향을 주지 않습니다.
  2. 재사용성 증가: ViewModel은 View에 종속되지 않으므로, 동일한 ViewModel을 다양한 View에서 재사용할 수 있습니다.
  3. 테스트 용이성: ViewModel은 View와 독립적이기 때문에, UI 테스트 없이 비즈니스 로직을 유닛 테스트할 수 있습니다.
  4. 데이터 바인딩의 이점: MVVM 패턴은 데이터 바인딩을 통해 View와 ViewModel 간의 자동 데이터 업데이트를 제공합니다. 이는 코드의 양을 줄이고, View와 ViewModel 간의 상호작용을 간소화합니다.

4. MVVM 패턴의 단점

  1. 초기 설정의 복잡성: MVVM 패턴을 처음 도입할 때, ViewModel과 데이터 바인딩을 설정하는 작업이 복잡할 수 있으며, 작은 프로젝트에서는 오히려 불필요한 복잡성을 초래할 수 있습니다.
  2. 데이터 바인딩의 오버헤드: 데이터 바인딩은 실시간으로 데이터를 업데이트하는 데 도움이 되지만, 성능에 영향을 미칠 수 있습니다. 특히, 많은 데이터가 동시에 처리될 때 성능 저하가 발생할 수 있습니다.

5. MVVM 패턴의 실용 예시

5.1. 모델 (Model)

모델은 데이터를 정의하고, 데이터의 상태 변화를 관리하는 역할을 합니다.

public class UserModel
{
    public string Name { get; set; }
    public int Age { get; set; }

    public UserModel(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

5.2. 뷰모델 (ViewModel)

ViewModel은 모델의 데이터를 처리하고, View와 데이터를 주고받는 역할을 합니다.

public class UserViewModel : INotifyPropertyChanged
{
    private UserModel _user;

    public UserViewModel()
    {
        _user = new UserModel("John", 25);
    }

    public string UserName
    {
        get { return _user.Name; }
        set
        {
            _user.Name = value;
            OnPropertyChanged("UserName");
        }
    }

    public int UserAge
    {
        get { return _user.Age; }
        set
        {
            _user.Age = value;
            OnPropertyChanged("UserAge");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

5.3. 뷰 (View)

뷰는 ViewModel의 데이터를 시각적으로 보여주고, 사용자 입력을 ViewModel에 전달하는 역할을 합니다.
WPF 예시로는 XAML을 통해 데이터 바인딩을 할 수 있습니다.

<Window x:Class="MVVMExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MVVM Example" Height="200" Width="300">

    <Grid>
        <StackPanel>
            <TextBox Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" />
            <TextBox Text="{Binding UserAge, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
    </Grid>
</Window>

위의 XAML 코드에서, UserName과 UserAge는 ViewModel에 바인딩되어 있으며, 사용자가 값을 변경하면 ViewModel이 자동으로 업데이트됩니다.

5.4. MVVM 구현 예시

다음은 MVVM 패턴을 사용하는 간단한 예시입니다:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new UserViewModel(); // 뷰모델을 뷰의 데이터 컨텍스트로 설정
    }
}

6. MVVM 패턴의 사용 사례

  • WPF: MVVM 패턴은 WPF 애플리케이션에서 UI와 비즈니스 로직을 분리하는 데 널리 사용됩니다. WPF의 강력한 데이터 바인딩 기능과 자연스럽게 통합됩니다.
  • Xamarin.Forms: 크로스플랫폼 모바일 개발에서 UI와 로직을 분리하여 유지보수를 쉽게 하기 위해 MVVM 패턴이 자주 사용됩니다.
  • Unity: MVVM 패턴은 Unity에서 사용자 인터페이스와 게임 로직을 분리하는 데에도 활용되며, 특히 데이터 바인딩을 사용하여 코드의 양을 줄일 수 있습니다.

MVVM 패턴은 UI와 비즈니스 로직의 분리를 극대화하여 유지보수성과 확장성을 높이는 매우 유용한 디자인 패턴입니다. 특히, WPF와 같은 데이터 바인딩을 지원하는 프레임워크와 결합되었을 때 그 효율성을 발휘합니다. 이 패턴을 통해 UI와 로직을 독립적으로 관리하고 테스트할 수 있으며, 코드 재사용성을 크게 높일 수 있습니다.