MVC,MVP, MVVM 패턴의 가중 중요한 점
MVC, MVP, MVVM 패턴에서 가장 중요한 것은 MV 부분입니다.
위 패턴을 설명하는 블로그나 다른 곳들에서 MV의 중요성을 강조하는 곳이 없어서 매우 안타깝습니다. 사실 MV 부분만 잘 설계하면 나머지는 상황에 맞게 설계할 수 있다고 생각합니다.
Model(모델 ): 속성과 값을 저장하는 곳입니다.
View(뷰) : 모델의 값을 보여주는 곳입니다.
이것이 전부입니다. 복잡하게 이해할 필요가 없습니다.
뷰는 값을 저장하지 않고, 모델에 저장합니다.
뷰는 모델에 저장된 값을 보여주는 용도로 사용됩니다.
이 점만 이해하면 이 세 가지 패턴의 90% 이상을 이해한 것입니다.
코드를 예시로 보이면 아래와 같습니다.
// Model (점수 데이터)
public class ScoreModel
{
public int score;
}
// View (점수를 표시하는 UI)
public class ScoreView : MonoBehaviour
{
public Text scoreText;
public void UpdateScoreDisplay(int score)
{
scoreText.text = "Score: " + score;
}
}
C#
복사
왜 MV를 분리해야 하는가
MV를 분리해야 하는 이유는 많지만, 가장 중요한 하나를 깊게 설명하고 나머지는 간단히 설명하겠습니다.
모델과 뷰를 분리하는 가장 중요한 이유는 서로의 의존성을 끊기 위함입니다.
간단히 말해, A라는 몬스터가 HP, 공격력 등의 정보를 GameObject, 즉 뷰에 저장되어 있다고 가정합시다.
이 경우, 뷰가 사라지면 모델도 그 정보를 잃게 됩니다. 또한, 그 정보를 찾기도 쉽지 않죠.
만약 몬스터가 어떤 스킬을 사용하다가 죽어서 모델을 잃어버렸다면, 그 스킬을 어떻게 처리할지 결정하기 어렵습니다.
다음은 위 이유 다음으로 모델과 뷰를 분리해야 하는 중요한 이유입니다.
1.
유지 보수의 용이성 : Model과 View를 분리함으로써, 각각 독립적으로 변경하고 유지 보수할 수 있습니다. 예를 들어, 게임의 모델을 변경할 때 UI를 건드리지 않아도 되며, 반대의 경우도 마찬가지입니다.
2.
재사용성 향상 : Model은 View나 특정 UI 요소와 독립적으로 작동하므로, 다양한 View에서 재사용할 수 있습니다.
a.
간단하게 말해서 유저의 HP와 연관된 모든 부분들을 쉽게 UI에 표시할 수 있습니다.
3.
복잡성 관리 : 큰 규모의 게임 프로젝트는 복잡할 수 있으며, MV의 분리는 이러한 복잡성을 관리하는 데 도움이 됩니다. 각 부분이 명확한 역할과 책임을 가지므로, 개발 팀은 코드베이스를 더 쉽게 이해하고 관리할 수 있습니다.
a.
조금 어렵게 설명을 했는데, 모델은 완벽한테 뷰에서 문제가 생기는 경우는 뷰를 담당하는 개발자가 그 부분에 문제를 해결할 수 있습니다.
b.
혹은, 복잡한 모델들을 혼합해서 사용하는 경우 그 모델들을 하나하나 추적함으로 써 어떤 모델에서 문제가 생겼는지 확인할 수 있습니다.
4.
성능 최적화 : 렌더링(뷰)과 데이터 처리(모델)를 분리함으로써, 성능 최적화가 더 명확하고 효율적으로 이루어질 수 있습니다. 예를 들어, 무거운 데이터 처리가 UI 성능에 영향을 미치지 않도록 할 수 있습니다.
a.
저는 의존성 다음으로 가장 중요하다고 생각하는 부분이 이 부분입니다. 뒤에서 돌아가는 로직의 경우, 모델과 뷰를 분리하면 뷰가 처리할 필요가 없습니다. 게임 개발에서는 그래픽 처리 부분에서 99% 이상의 성능 이슈가 발생하므로, 이 부분을 효과적으로 활용하면 성능 최적화에 매우 좋다고 생각합니다.
MVC
MVC (Model-View-Controller)
•
Model : 데이터와 로직을 관리합니다. 유니티에서는 게임의 상태, 로직, 데이터 등을 처리합니다.
•
View : 사용자 인터페이스(UI)를 담당합니다. 유니티에서는 게임 오브젝트와 UI 요소들이 이에 해당합니다.
•
Controller: 사용자 입력을 받아 모델을 업데이트하고, 뷰를 갱신합니다. 유니티에서는 사용자 입력을 처리하고 게임의 흐름을 제어하는 스크립트가 이 역할을 합니다.
이후 소개할 MV 관련 부분들은 모두 동일한 설명을 제공할 예정입니다. MVC, MVP, MVVM의 차이점은 마지막 부분 C,P,VM에서만 찾아볼 수 있습니다.
Model
public class GameModel
{
public int Score { get; private set; }
public void IncreaseScore(int value)
{
Score += value;
}
}
C#
복사
View
using UnityEngine;
using UnityEngine.UI;
public class GameView : MonoBehaviour
{
public Text scoreText;
public GameModel gameModel;
public void UpdateScore(int score)
{
scoreText.text = "Score: " + gameModel.Score.ToString();
}
}
C#
복사
Controller
using UnityEngine;
public class GameController
{
public GameModel model;
public GameView view;
private void IncreaseScore()
{
model.IncreaseScore(10);
view.UpdateScore(model.Score);
}
}
C#
복사
MVC에서 중요한 점은 모델과 뷰가 모델을 직접 알고 있다는 점입니다.
MVP
MVP (Model-View-Presenter)
•
Model : 데이터와 로직을 관리합니다. 유니티에서는 게임의 상태, 로직, 데이터 등을 처리합니다.
•
View : 사용자 인터페이스(UI)를 담당합니다. 유니티에서는 게임 오브젝트와 UI 요소들이 이에 해당합니다.
•
Presenter : View와 Model 사이의 중재자 역할을 하며, View의 이벤트를 처리하고 Model을 업데이트합니다.
이 부분은 코드가 간단하게 작성되면 MVC와 큰 차이점이 없습니다. 그러나 MVC는 여러 모델과 뷰를 한 번에 관리하는 반면, MVP는 단일 모델과 뷰를 직접적으로 관리합니다.
실제로 이 부분은 프로그래머의 설계 방식에 따라 달라질 수 있지만, 설명이 복잡해질 수 있으므로 여기서는 생략하겠습니다.
다시 한번 강조하자면, 가장 중요한 것은 MV의 분리입니다.
Model
public class PlayerModel
{
public float Health { get; private set; }
public void TakeDamage(float amount)
{
Health -= amount;
}
}
C#
복사
View
using UnityEngine;
using UnityEngine.UI;
public class PlayerView : MonoBehaviour
{
public Text healthText;
// MVC 패턴과 다르게 MVP 패턴에서 View는 모델을 직접 알 수 없습니다.
public void UpdateHealth(float health)
{
healthText.text = "Health: " + health.ToString();
}
}
C#
복사
Presenter
public class PlayerPresenter
{
private PlayerModel model;
private PlayerView view;
// MVC 패턴에서와 다르게 MVP 에서는 이런식으로 모델과 뷰를 직접적으로 연결하는 부분이 있습니다.
// 그래서 여러 Presenseter를 관리할 때는 따로 매니저를 통해 한 번에 관리하기도 합니다.
public void Initialize(PlayerView view)
{
this.view = view;
this.model = new PlayerModel();
}
public void OnDamageTaken(float amount)
{
model.TakeDamage(amount);
view.UpdateHealth(model.Health);
}
}
C#
복사
MVVM
MVVM (Model-View-ViewModel)
•
Model : 데이터와 로직을 관리합니다. 유니티에서는 게임의 상태, 로직, 데이터 등을 처리합니다.
•
View : 사용자 인터페이스(UI)를 담당합니다. 유니티에서는 게임 오브젝트와 UI 요소들이 이에 해당합니다.
•
ViewModel : View를 위한 데이터와 명령을 준비하고, Model과 View 사이의 바인딩을 관리합니다.
MVVM은 Unirx에서 사용하는 패턴입니다. 따라서 Unirx를 사용하는 분들은 이 라이브러리를 사용하면서, MVVM에 대해 좀 더 깊게 이해할 수 있을 것입니다.
MVVM에서 View는 ViewModel을 참조합니다.
ViewModel은 Model의 데이터를 가공하여 View에 제공합니다. 바인딩을 통해 Model의 변경이 자동으로 View에 반영됩니다.
Model
public class UserProfile
{
public string Name { get; set; }
public string Email { get; set; }
// Constructor
public UserProfile(string name, string email)
{
Name = name;
Email = email;
}
}
C#
복사
View
public class UserProfileView : MonoBehaviour
{
public Text nameText;
public Text emailText;
private UserProfileViewModel viewModel;
void Start()
{
// 원래 이 부분들은 다른 곳에서 제작해서 viewModel만 주입받습니다.
UserProfile user = new UserProfile("John Doe", "john@example.com");
viewModel = new UserProfileViewModel(user);
// 여기에서 변경 사항에 대한 변화 액션을 등록.
viewModel.SetNameChange(OnNameChanged);
}
private void UpdateNameView()
{
nameText.text = viewModel.Name;
}
public void OnNameChanged(string newName)
{
UpdateView();
}
}
C#
복사
ViewModel
public class UserProfileViewModel
{
private readonly UserProfile user;
private UnityAction<string> nameChangeAction;
private UnityAction<string> emailChangeAction;
public string Name
{
get => user.Name;
set
{
user.Name = value;
// 필요한 경우 데이터 변화를 알리는 로직
nameChangeAction?.Invoke();
}
}
public string Email
{
get => user.Email;
set
{
user.Email = value;
// 데이터 변화 알림 로직
emailCahngeAction?.Invoke();
}
}
public UserProfileViewModel(UserProfile user)
{
this.user = user;
}
// 각 액션을 처리하는 로직 ...
}
C#
복사