MVVM은 UI를 작성할 때 많이 사용하는 기법 중 하나이다.
보통 MVC, MVP도 사용을 하지만 MVVM의 장점이 뛰어나 MVVM을 많이 사용하곤 한다.
MVP와 MVVM은 비슷하지만 다른데, MVP는 Presenter가 view마다 하나씩 존재해야하므로 view가 늘어날 수록 점점 더 많은 presenter가 필요한 반면, MVVM은 그렇지 않다.
MVVM을 적용한 간단한 코드를 살펴보겠다.
Model은 간단하므로 ViewModel에 작성하였다.
//viewModel
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using UnityEngine;
public class ViewModel : INotifyPropertyChanged
{
private String _text = "";
public String text
{
get => _text;
set
{
if (Equals(value, _text)) return;
_text = value;
OnPropertyChanged("Text");
}
}
private int _point = 0;
public int point { get => _point;
set
{
if (Equals(value, _point)) return;
_point = value;
OnPropertyChanged("Point");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if(PropertyChanged != null)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
INotifyPropertyChanged를 사용하였다. 이때 OnPropertyChanged라는 method구현이 필수가 된다. text와 point의 값이 바뀔 때 우리는 OnPropertyChanged를 호출하게 된다.
다음은 view이다.
//view
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.UI;
public class View : MonoBehaviour
{
ViewModel viewModel;
private Text text;
// Start is called before the first frame update
void Start()
{
viewModel = Managers.gm.viewModel;
text = GetComponent<Text>();
viewModel.PropertyChanged += OnPlayerViewModelPropertyChanged;
viewModel.text = "hi";
}
private void OnPlayerViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Text")
{
viewModel.text = "re-Hi";
text.text = viewModel.text;
}
else if (e.PropertyName == "Point")
{
//viewModel.text = "ScoreUp";
text.text = viewModel.point.ToString();
}
}
}
/button
public class UI_Controller : MonoBehaviour, IBeginDragHandler, IDragHandler
{
private Button button;
private void Start()
{
button = GetComponent<Button>();
button.onClick.AddListener(PointUp);
}
void PointUp()
{
Managers.gm.viewModel.point++;
}
}
button을 누르게 되면 viewModel의 Binding되어 있던 point의 값이 바뀌게 되며 자동으로 UI에 갱신되는 것을 확인할 수 있다.