MVVM을 사용하여 더 나은 어플리케이션 만들기
배경.
한 달 전까지만 해도 그래픽 사용자 인터페이스를 만든 경험은 일반적인 HTML/CSS 사이트와 appJar을 사용하는 기본python 응용 프로그램에만 한정되었다.나는 항상 GUI를 사용해야 한다는 개념에 놀랐다. 백엔드를 대상으로 하는 프로그래머로서 나의 사고방식은 유행의 틀과 잘 맞지 않는 것 같다.
최근에 나는 어쩔 수 없이 나의 decentralized social media을 위해 데스크톱 클라이언트를 개발하기 시작했다.대다수의 사람들이 동의할 것이다. 이것은 두려운 프로젝트이며, 특히 경험이 부족한 전단 개발자에게는 그렇다.처음에 나는 MVVM에 대해 알게 될 때까지 진보하기 어렵다는 것을 알았다.
MVVM이란 무엇입니까?
MVVM은 모델, 뷰, 뷰 모델을 나타냅니다.MVVM 애플리케이션의 세 가지 주요 부분을 구성합니다.
모델
모델은 응용 프로그램이 사용하는 핵심 알고리즘과 데이터 구조인'업무 논리'를 포함한다.그것들은 보통 '순수' 프로그래밍 언어로 작성되며, 특별한 라이브러리를 사용하지 않는다.
모델 보기
뷰 모델은 뷰 상태를 나타내는 특수 클래스입니다.예를 들어 텍스트를 표시하거나 사용자가 입력한 텍스트 상자 또는 다른 뷰 모델을 나타내는 속성이 있습니다.이벤트를 나타내는 기능/명령도 있어야 합니다(예를 들어 단추를 눌렀을 때).
뷰 모델에는 일반적으로 템플릿 코드가 있으므로 현재 사용 중인 MVVM 프레임워크와 통합할 수 있습니다.그러나 보기에 의존하지 않고 독립적으로 일해야 한다.
소견
보기에는 UI에서 사용하는 코드가 포함되어 있습니다.일반적으로 XAML 또는 HTML 등의 태그 언어로 작성됩니다.보기는 보기의 구조(과 스타일)를 개괄하고 그 내용은 귀속을 통해 설정됩니다.
귀속은 내용을 보기 모델에 연결할 수 있는 속성입니다.뷰 모델의 속성을 변경하면 뷰에 표시되는 내용이 자동으로 업데이트됩니다.귀속도 다른 방식으로 작업할 수 있으며 양방향 귀속을 사용할 수 있다.이것은 키를 눌렀을 때마다 보기 모델 속성을 업데이트할 수 있기 때문에 텍스트 상자에 유용합니다. (이것은 실시간 입력 검증에 사용할 수 있습니다.)
간단한 예
제가 방금 말씀드린 아이디어를 보여드리기 위해서 MVVM을 사용하여 프로그램을 만드는 과정을 신속하게 안내해 드리겠습니다.이 프로그램은 사용자가 인원 목록을 클릭할 수 있도록 할 것이다.
WPF(Windows 데모 프레임워크)를 사용합니다.계속하려면 VisualStudio에서 새
WPF App (.NET)
프로젝트를 만듭니다.제 전화번호는 Demo
입니다.모델 생성하기
우선, 우리는 한 사람을 나타내는 클래스를 만들 것이다.이 필드는
Name
과 Age
두 필드로 구성됩니다.나는 이미 이 종류를
Demo.Models
명칭 공간에 넣고 Models/PersonModel.cs
으로 저장했다.public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public PersonModel(string name, int age)
{
Name = name;
Age = age;
}
}
뷰 모델 생성하기
다음에 우리는 보기 모형을 만들 것이다.네 개의 속성이 있습니다. - 두 개의 문자열과 두 개의 명령이 있습니다.문자열은 현재 보이는 사람의 이름과 나이를 표시하고, 단추를 누르면 이들을 클릭할 수 있습니다.
속성을 변경할 때마다 뷰를 업데이트할 수 있도록 프레임에 경고해야 합니다.WPF에서는
INotifyPropertyChanged
을 구현한 다음 속성을 설정할 때 NotifyPropertyChanged
을 호출하여 구현합니다.나는 이미 이 종류를
Demo.ViewModels
명칭 공간에 넣고 ViewModels/PeopleViewModel.cs
으로 저장했다.public class PeopleViewModel : INotifyPropertyChanged
{
//// Bindable properties
private string _name;
public string Name
{
get => _name;
private set
{
_name = value;
NotifyPropertyChanged(nameof(Name));
}
}
private string _age;
public string Age
{
get => _age;
private set
{
_age = value;
NotifyPropertyChanged(nameof(Age));
}
}
public ICommand Previous { get; init; }
public ICommand Next { get; init; }
//// Implementation
private PersonModel[] people = new PersonModel[] {
new PersonModel("Alice", 20),
new PersonModel("Bob", 25),
new PersonModel("Charlie", 30)
};
private int index = 0;
public PeopleViewModel()
{
Name = people[index].Name;
Age = people[index].Age.ToString();
Previous = new RelayCommand(() =>
{
if (index > 0)
{
index--;
Name = people[index].Name;
Age = people[index].Age.ToString();
}
});
Next = new RelayCommand(() =>
{
if (index < people.Length - 1)
{
index++;
Name = people[index].Name;
Age = people[index].Age.ToString();
}
});
}
//// Boilerplate code to satisfy INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged is null) return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
이 예에서 RelayCommand
류는 함수를 ICommand
으로 포장하는 데 사용된다.이에 대한 설명(그리고 이 종류의 코드)은 here에서 찾을 수 있다.왜 나이가 정수가 아니에요?
age 속성은 정수가 아닙니다. 왜냐하면 이것은 사람의 나이를 대표하지 않기 때문입니다. 이것은 표시된 내용을 대표합니다.보기는 문자열을 표시하기 때문에 속성의 유형은string이어야 합니다.
뷰 생성하기
현재 보기 모형이 생성되었습니다.
UserControl
을 보기로 만들 것입니다.두 개의 탭과 두 개의 단추가 있습니다. 탭은 이름과 나이 문자열에 연결되고, 단추는 이전 명령과 다음 명령에 연결됩니다.WPF에는 뷰당
DataContext
이 있습니다.Demo.ViewModels
명칭 공간을 포함함으로써 우리는 사용자 컨트롤의 데이터 상하문을 PersonViewModel
으로 설정할 수 있다.그리고 우리는 X
문법으로 UserControl.DataContext
의 속성 "{Binding X}"
에 귀속할 수 있다.사용자 컨트롤을
Views/PeopleView.xaml
으로 저장했습니다.<UserControl x:Class="Demo.Views.PeopleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewmodels="clr-namespace:Demo.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<viewmodels:PeopleViewModel />
</UserControl.DataContext>
<StackPanel Background="White">
<Label Content="{Binding Name}" />
<Label Content="{Binding Age}" />
<StackPanel Orientation="Horizontal">
<Button Content="Previous" Command="{Binding Previous}" />
<Label />
<Button Content="Next" Command="{Binding Next}" />
</StackPanel>
</StackPanel>
</UserControl>
그럼 뒤에 코드는요?
코드 숨김은 MVVM을 사용하는 WPF 응용 프로그램에서 거의 사용되지 않습니다.모든 UI 논리는 숨겨진 코드가 아닌 뷰 모델에 포함되어야 합니다.이러한 관심사의 분리는 바로 MVVM이 이렇게 다기능 체계 구조가 된 원인이다!
끝맺다
현재 보기를 만들었습니다.
MainWindow.xaml
에 표시할 수 있습니다.<Window x:Class="Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:Demo.Views"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<views:PeopleView />
</StackPanel>
</Window>
런타임 시 애플리케이션이 예상대로 작동하는 것을 보아야 합니다.왜 이렇게 열심히 해요?
너는 우리가 왜 이렇게 노력해야 하는지 알고 싶을 것이다.MVVM이 표준 [코드 숨김] 방법보다 우수한 데는 세 가지 주요 이유가 있습니다.
테스트 가능성
뷰 모델과 뷰가 완전히 결합되어 있으므로 UI를 직접 테스트하지 않고도 테스트 프레임워크(예: MSTest)를 사용하여 인터페이스 논리가 정확한지 확인할 수 있습니다.
모듈화
모델과 보기 모델을 만들었으니 코드에서 구성 요소로 다시 사용할 수 있습니다.예를 들어, 다음과 같이 어셈블리의 두 번째 인스턴스를 추가할 수 있습니다.
<StackPanel>
<views:PeopleView />
<views:PeopleView />
</StackPanel>
구성 요소를 서로 끼워 넣으면 최소한의 작업량으로 복잡하고 모듈화된 사용자 인터페이스를 구축할 수 있습니다.
같은 보기 모형에 연결된 여러 보기를 만들 수 있습니다!나는
DataContext
의 MainWindow
을 새로운 PersonViewModel
으로 설정하고 이 두 보기를 그것에 연결한다.<Window x:Class="Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodels="clr-namespace:Demo.ViewModels"
xmlns:views="clr-namespace:Demo.Views"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<viewmodels:PeopleViewModel />
</Window.DataContext>
<StackPanel>
<views:PeopleView DataContext="{Binding}" />
<views:PeopleView DataContext="{Binding}" />
</StackPanel>
</Window>
주의: 보통 보기의
DataContext
속성을 현재 보기 모델의 속성에 연결합니다.그러나 메인 창에 보기 모형이 없기 때문에 Window.DataContext
으로 직접 연결합니다.플랫폼 불가지론
응용 프로그램을 세 부분으로 나누면 여러 플랫폼에서 모델을 다시 사용하고 모델을 볼 수 있다.MvvmCross(Windows, Mac, iOS, 안드로이드 지원) 등 플랫폼 간 프레임워크를 사용하면 이 점이 쉬워진다.
결론
MVVM은 테스트, 모듈식 및 플랫폼 간 어플리케이션을 개발할 수 있는 어플리케이션 아키텍처입니다.코드는 세 부분으로 나뉘어져 있습니다.
각주
만약 당신이 이 글을 읽는 것을 좋아한다면 비슷한 글을 쓰거나 나를 따라오는 것을 고려해 보세요.
면책 성명 - 저는 독학으로 인재가 된 프로그래머입니다. 저는 블로그로 더 좋은 개발자가 되는 과정에서 배운 것을 공유합니다.나는 내가 저지른 모든 잘못에 대해 미리 사과한다. 비판과 정정을 환영한다.
Reference
이 문제에 관하여(MVVM을 사용하여 더 나은 어플리케이션 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mileswatson/a-beginners-guide-to-mvvm-using-c-wpf-241b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)