본문 바로가기
Languages/C#

Day 9: MVVM 디자인 패턴 소개 및 구현

by 반도체는 프로그래밍을 좋아해 2023. 4. 10.
728x90

MVVM(Model-View-ViewModel) 패턴은 WPF, Xamarin, UWP 등의 XAML을 이용한 개발에서 주로 사용되는 디자인 패턴입니다.

MVVM 패턴은 각각의 역할을 분리하여 코드의 유지보수성과 확장성을 높이는 장점이 있습니다. 아래는 MVVM 패턴의 3가지 구성요소입니다.

  • Model : 비즈니스 로직과 데이터를 처리하는 부분입니다.
  • View : 사용자 인터페이스(UI)를 담당하는 부분입니다.
  • ViewModel : Model과 View 사이에서 데이터를 처리하고 View에 전달하는 부분입니다.

MVVM 패턴에서는 View와 ViewModel 사이에 데이터 바인딩을 사용하여 ViewModel에서 데이터를 처리하면 View에 자동으로 반영되도록 합니다. 이를 통해 ViewModel과 View 간의 의존성을 줄이고 유지보수성을 높일 수 있습니다.

MVVM 패턴을 사용하면 코드를 더욱 간결하고 유연하게 작성할 수 있습니다. 또한, ViewModel과 View를 분리함으로써 동시에 여러 개발자가 작업할 수 있는 효율적인 작업 분담이 가능합니다.

MVVM 패턴은 이러한 장점을 통해 XAML을 이용한 개발에서 널리 사용되고 있으며, WPF, Xamarin, UWP 등의 플랫폼에서 쉽게 적용할 수 있습니다.

 

예를 들어) 학생 정보를 관리하는 어플리케이션을 만들려고 한다고 가정해봅시다. 이 어플리케이션은 학생 정보를 보여주는 화면과 학생 정보를 추가하고 삭제하는 화면을 갖고 있습니다.

이때, MVVM 패턴을 사용하여 아래와 같이 구조화할 수 있습니다.


1. Model

  • 데이터와 데이터 조작을 담당합니다.
  • 예를 들어, 위의 예시에서는 학생 객체와 학생 추가/삭제와 같은 데이터 조작 메서드가 이에 해당합니다.
// Model
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}

public class StudentModel
{
	private ObservableCollection<Student> studentList;
    public StudentModel()
    {
        studentList = new ObservableCollection<Student>();
    }

    public void AddStudent(Student student)
    {
        studentList.Add(student);
    }

    public void RemoveStudent(Student student)
    {
        studentList.Remove(student);
    }

    public ObservableCollection<Student> GetStudents()
    {
        return studentList;
    }
}


2. View

  • 사용자 인터페이스(UI)를 담당합니다.
  • 예를 들어, 위의 예시에서는 학생 정보를 보여주는 화면과 학생 추가/삭제를 할 수 있는 UI가 이에 해당합니다.
//xaml
<Window x:Class="Namespace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:YourNamespace"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <DataTemplate x:Key="StudentTemplate">
            <StackPanel>
                <TextBlock Text="{Binding Id}" />
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding Age}" />
                <Button Content="Remove" Command="{Binding RemoveStudentCommand}" CommandParameter="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="ID:" />
                <TextBox x:Name="StudentId" Width="100" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Name:" />
                <TextBox x:Name="StudentName" Width="100" />
            </StackPanel>
            <Button Content="Add Student" Click="AddStudent_Click" />
            <ListBox ItemsSource="{Binding StudentList}" ItemTemplate="{StaticResource StudentTemplate}" />
        </StackPanel>
    </Grid>
</Window>

//xaml.cs

// View
public partial class MainWindow : Window
{
    private StudentViewModel viewModel;
    public MainWindow()
    {
        InitializeComponent();
        viewModel = new StudentViewModel();
        DataContext = viewModel;
    }

    private void AddStudent_Click(object sender, RoutedEventArgs e)
    {
        Student student = new Student();
        student.Id = int.Parse(StudentId.Text);
        student.Name = StudentName.Text;
        viewModel.AddStudentCommand.Execute(student);
    }

    private void RemoveStudent_Click(object sender, RoutedEventArgs e)
    {
        Student student = (sender as Button).DataContext as Student;
        viewModel.RemoveStudentCommand.Execute(student);
    }
}

 

3. ViewModel

  • View와 Model 간의 인터페이스 역할을 합니다.
  • View에서 발생한 이벤트를 받아서 Model에 전달하고, Model에서 발생한 데이터 변경 사항을 View에 전달합니다.
  • 예를 들어, 위의 예시에서는 학생 정보를 보여주는 UI에서 학생 추가/삭제 버튼 클릭 이벤트를 받아서 Model에 전달하고, Model에서 데이터 변경이 발생하면 View에 해당 변경을 전달합니다.
// ViewModel
public class StudentViewModel
{
    private StudentModel model;
    public StudentViewModel()
    {
        model = new StudentModel();
        AddStudentCommand = new RelayCommand<Student>(AddStudent);
        RemoveStudentCommand = new RelayCommand<Student>(RemoveStudent);
    }

    public ObservableCollection<Student> Students
    {
        get { return model.GetStudents(); }
    }

    public ICommand AddStudentCommand { get; private set; }

    public ICommand RemoveStudentCommand { get; private set; }

    private void AddStudent(Student student)
    {
        model.AddStudent(student);
    }

    private void RemoveStudent(Student student)
    {
        model.RemoveStudent(student);
    }
}


위의 예시에서 MVVM 패턴을 적용하면, 각각의 클래스는 아래와 같은 역할을 수행합니다.

1. Model : Student 클래스와 AddStudent(), RemoveStudent() 메서드를 갖습니다.
2. View : 학생 정보를 보여주는 UI와 학생 추가/삭제 UI를 갖습니다.
3. ViewModel : StudentList ObservableCollection과 AddStudentCommand, RemoveStudentCommand를 갖습니다.


 

MVVM 패턴은 WPF, Silverlight, Xamarin 등의 프레임워크에서 주로 사용되며, View와 Model 간의 결합도를 낮추고, 유지보수성과 확장성을 높일 수 있는 장점이 있습니다. 특히, 개발자는 UI와 비즈니스 로직을 분리할 수 있으므로, 효율적인 개발이 가능합니다.

MVVM 패턴은 애플리케이션의 크기가 작은 경우에는 구현하기 번거롭고 비효율적일 수 있지만크기가 커지면서 유지보수와 확장성이 필요한 경우에는 매우 유용한 패턴입니다.

그리고 이번 블로그에서는 MVVM 패턴을 구현하기 위한 기본적인 구조와 각 구성 요소의 역할에 대해 알아보았습니다. 이를 통해 더 효율적이고 유지보수성이 높은 애플리케이션을 개발할 수 있도록 도움이 되었기를 바랍니다.

728x90

'Languages > C#' 카테고리의 다른 글

C# WPF 병합된 리소스(Merged Resource)  (0) 2023.04.10
C# WPF Ellipse  (0) 2023.04.10
C# 추상 클래스(abstract class) 와 인터페이스(interface)  (0) 2023.04.07
C# Indexer  (0) 2023.04.07
Day 8: WPF 커스텀 컨트롤 만들기  (0) 2023.04.07