24
MVVM(Model-View-ViewModel) 패턴은 주로 WPF, UWP, Xamarin.Forms 등에서 사용되는 소프트웨어 아키텍처 패턴으로, UI와 비즈니스 로직을 분리하여 코드의 유지 보수성과 확장성을 높이는 데 도움을 줍니다. 이 패턴은 MVC(Model-View-Controller)에서 발전된 형태로, 데이터 바인딩 기능을 활용해 뷰와 데이터의 동기화를 자동으로 관리합니다.
MVVM 구성 요소
- Model: 데이터와 비즈니스 로직을 담당하며, 주로 데이터 구조 및 데이터베이스와의 상호작용을 처리합니다.
- View: 사용자 인터페이스(UI)를 담당하며, XAML로 작성된 화면을 의미합니다.
- ViewModel: 뷰와 모델 간의 중간자 역할을 하며, 뷰의 데이터 바인딩을 통해 뷰와 상호작용합니다. ViewModel은 명령과 프로퍼티를 통해 뷰의 동작을 제어하고 데이터 상태를 유지합니다.
MVVM 예제 코드
이 예제는 간단한 MVVM 패턴의 구현으로, Name
속성에 입력한 값을 UI에 표시합니다.
Model (데이터 클래스)
public class Person
{
public string Name { get; set; }
}
View (XAML)
<Window x:Class="WpfApp.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="400">
<Grid>
<StackPanel>
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Width="200" Margin="10"/>
<Button Content="Show Name" Command="{Binding ShowNameCommand}" Width="100" Margin="10"/>
</StackPanel>
</Grid>
</Window>
ViewModel (뷰모델)
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
public class MainViewModel : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public ICommand ShowNameCommand { get; }
public MainViewModel()
{
ShowNameCommand = new RelayCommand(ShowName);
}
private void ShowName()
{
MessageBox.Show($"Hello, {Name}!");
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
RelayCommand 클래스 (명령 구현)
using System;
using System.Windows.Input;
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
View 연결 (Code-behind)
using System.Windows;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
}
실행 사진
코드 설명:
- Model:
Person
클래스는Name
속성만 포함하는 단순한 데이터 클래스입니다. - View: XAML 파일에서
TextBox
는Name
속성과 바인딩되고,Button
은ShowNameCommand
명령과 바인딩됩니다. - ViewModel:
MainViewModel
클래스는INotifyPropertyChanged
인터페이스를 구현하여Name
속성 변경 시 뷰에 자동으로 알립니다.ShowNameCommand
는 버튼 클릭 시ShowName()
메서드를 실행합니다.
- RelayCommand: 간단한 명령을 생성하는 유틸리티 클래스로,
ICommand
인터페이스를 구현하여 명령을 실행하고 상태를 확인할 수 있게 합니다. - View 연결:
MainWindow
에서DataContext
를MainViewModel
인스턴스로 설정하여 뷰와 뷰모델을 연결합니다.
MVVM의 장점:
- 유지보수성: 코드와 UI의 분리로 유지보수가 쉽습니다.
- 테스트 용이성: 뷰모델이 로직을 포함하기 때문에 단위 테스트가 더 쉽습니다.
- 재사용성: 뷰모델은 특정 뷰에 종속되지 않으므로 여러 뷰에서 재사용이 가능합니다.
이 예제를 통해 MVVM 패턴의 기본 구조와 동작 방식을 이해할 수 있습니다.