1 MVC :
Model - 원본 데이터, 프로퍼티 콜백 구현으로 View로 데이서 쏴줌
View - Model의 람다함수에 함수 등록 -> 자동 업데이트
Controller - View의 ex) OnClick함수에 의해 입력된 데이터를 Controller에 전달 -> Model값 수정
public static class Const
{
public enum Stat
{
STR, //공격력, 체력
AGI, //회피율
WIS, //공격력, 스킬데미지(전체)
LUC, //치명타 데미지
HP, //체력, 체력회복
MP, //마력, 마력 회복
Count,
}
}
// Model
DataManager.cs
public event Action<Dictionary<Const.Stat, int>> OnPlayerStatChanged;
public Dictionary<Const.Stat, int> playerStatDic;
public Dictionary<Const.Stat, int> PlayerStatDic
{
get { return playerStatDic;}
set {
playerStatDic = value;
OnPlayerStatChanged?.Invoke(playerStatDic);
}
}
// View
UI_StatPopup.cs or UI_StatPopupView.cs
public Dictionary<Const.Stat, Button> statButtonDic;
public Dictionary<Const.Stat, Text> statTextDic;
private void Start()
{
Managers.Data.OnPlayerStatChanged += HandleOnPlayerStatChanged;
for(Const.Stat stat = 0 ; stat < Const.Stat.Count ; stat++)
statButtonDic[stat].onClick.AddListener(() => OnClickStatButton(stat));
}
private void OnClickStatButton(Const.Stat _stat)
{
Managers.Player.UpdatePlayerStat(_stat, 1);
}
private void HandleOnPlayerStatChanged(Dictionary<Const.Stat, int> _statDic)
{
for(Const.Stat stat = 0 ; stat < Const.Stat.Count ; stat++)
statTextDic[stat].text = $"현재{stat} : {_statDic[stat]}";
}
// Controller
// StateController.cs or StatSystem.cs or
// PlayerController.cs or PlayerSystem.cs
private void UpdatePlayerStat(Const.Stat _stat, int _value)
{
Manager.Data.PlayerStatDic[_stat] += _value;
}
MVC는 Stat같은 데이터 유형에 맞는거 같음
※특징 : Model과 View가 연결되어 있음
단, View는 직접적으로 Model값 수정 불가능, Controller 통해서만 값수정(장점이라 생각함)
※ 개인적으로 느낀 애로사항:
Controller가 굳이 필요없는 데이터 유형(ex. gold, dia 등) 과는 맞지 않는 것 같음.
MVC, MVP, MVMM 중 시간도 덜 걸리고 가장 간단하게 패턴을 구성 가능할 거 같음
stat처럼 ui를 통해서 user들이 올릴 수 있고, 또 stat은 player와도 관련이 있으니 player라는 controller나 system 싱글톤 스크립트를 생성하기에도 좋아서 요러한 stat 비스무리한 데이터들에 MVC를 적용하면 좋을듯 함!
또한 여러 게임들의 프로젝트를 분석한 결과 만약 Controller가 필요없는 유형 같은 경우에는 그냥 M과 V만 구성해서 구조짜는 듯한 것을 봤음. 단 이때 Controller의 역할이 Model값 수정하는 건데 이 때 딱히 유저가 ui를 통해서 올릴만한 데이터 유형이 아니라던지, Controller가 필요없고 여기저기 이스크립트 저스크립트 함수들에서 Model 원본 값에 직접 접근하여 올리는게 누가봐도 Controller 통하지 않는게 "코드의 양" 이라던지 "효율성 측면" 이라던지 이득이다 하는 그런 데이터 유형들은 Controller없이 M과V만 구성해서 구조짯음.
2.MVP
MVP의 핵심은 MVC의 M과V의 연결고리를 끊는 것이다. 그 연결고리는 Presenter가 대체해준다.
public static class Const
{
public enum Stat
{
STR, //공격력, 체력
AGI, //회피율
WIS, //공격력, 스킬데미지(전체)
LUC, //치명타 데미지
HP, //체력, 체력회복
MP, //마력, 마력 회복
Count,
}
}
// Model
DataManager.cs
public Dictionary<Const.Stat, int> playerStatDic;
public Dictionary<Const.Stat, int> PlayerStatDic
{
get { return playerStatDic;}
set { playerStatDic = value;}
}
// View
UI_StatPopup.cs or UI_StatPopupView.cs
public Dictionary<Const.Stat, Button> statButtonDic;
public Dictionary<Const.Stat, Text> statTextDic;
private void Start()
{
for(Const.Stat stat = 0 ; stat < Const.Stat.Count ; stat++)
statButtonDic[stat].onClick.AddListener(() => OnClickStatButton(stat));
}
private void OnClickStatButton(Const.Stat _stat)
{
Managers.Player.UpdatePlayerStat(_stat, 1);
}
public void Refresh(Dictionary<Const.Stat, int> _statDic)
{
for(Const.Stat stat = 0 ; stat < Const.Stat.Count ; stat++)
statTextDic[stat].text = $"현재{stat} : {_statDic[stat]}";
}
// Presenter
// StatePresentercs or StatSystem.cs or
// PlayerPresenter.cs or PlayerSystem.cs
public UI_StatPopupView ui_StatPopupView;
private void UpdatePlayerStat(Const.Stat _stat, int _value)
{
// 데이터 원본에 접근 -> 값 수정
Manager.Data.PlayerStatDic[_stat] += _value;
// View에 데이터 전달
ui_StatPopupView.Refresh(Manager.Data.PlayerStatDic);
}
private Dictionary<Const.Stat, int> GetPlayerStat()
{
return Managers.Data.PlayerStatDic;
}
핵심이 데이터는 한방향으로 들어가서 들어간 방향 반대로 고대로 나오는게 중요한 거 같음.
View는 Model에 직접 접근 및 관련이 없는게 특징임. UpdatePlayerStat함수에서 view에서 받은 데이터 고대로 다시 view의 ui에 접근에 수정하고 있음. 근데 궁금한게 UpdategStat 함수에서 View의 Refresh를 호출하는게 맞는 걸까? 너무 없어 보이기도 하고 뭔가 이게 MVP 구현이 맞는지도 잘 모르겠음. 구글링 해봐도 MVP 구현은 잘 나온게 없어서 비교해 볼 수가 없음.
내 생각은 이런식의 구현이 맞다면 MVP는 안쓸 거 같음 대신에 MVMM을 쓸 거 같음
3. MVVM
MVVM 에서 Model은 MVP의 모델처럼 순수 원본 데이터 가지고 있는 Model임
VM은 MVC에서의 M의 역할인 V로의 데이터 뿌려줌을 VM에서 대신 해줌
public static class Const
{
public enum Stat
{
STR, //공격력, 체력
AGI, //회피율
WIS, //공격력, 스킬데미지(전체)
LUC, //치명타 데미지
HP, //체력, 체력회복
MP, //마력, 마력 회복
Count,
}
}
// Model
DataManager.cs
public Dictionary<Const.Stat, int> playerStatDic;
public Dictionary<Const.Stat, int> PlayerStatDic
{
get { return playerStatDic;}
set { playerStatDic = value;}
}
// View Model
// PlayerViewModel.cs or PlayerSystem.cs
// Action
public event Action<Dictionary<Const.Stat, int>> OnPlayerStatChanged;
public Dictionary<Const.Stat, int> PlayerStatDic
{
get { return Managers.Data.PlayerStatDic;}
set
{
Managers.Data.PlayerStatDic = value;
OnPlayerStatChanged?.Invoke(Managers.Data.PlayerStatDic);
}
}
private void UpdatePlayerStat(Const.Stat _stat, int _value)
{
PlayerStatDic[_stat] += _value;
}
// View
UI_StatPopup.cs or UI_StatPopupView.cs
public Dictionary<Const.Stat, Button> statButtonDic;
public Dictionary<Const.Stat, Text> statTextDic;
private void Start()
{
for(Const.Stat stat = 0 ; stat < Const.Stat.Count ; stat++)
statButtonDic[stat].onClick.AddListener(() => OnClickStatButton(stat));
PlayerSystem.OnPlayerStatChanged += HandleOnPlayerStatChanged;
}
private void OnClickStatButton(Const.Stat _stat)
{
Managers.PlayerSystem.UpdatePlayerStat(_stat, 1);
}
public void HandleOnPlayerStatChanged(Dictionary<Const.Stat, int> _statDic)
{
for(Const.Stat stat = 0 ; stat < Const.Stat.Count ; stat++)
statTextDic[stat].text = $"현재{stat} : {_statDic[stat]}";
}
MVVM의 특징은 VM이 M의 데이터를 한번 덮어 쓰는 듯한 느낌을 줌. 순수 Model에 VM이 접근하여 수정 및 읽기가 가능함. 그리고 그 VM이 수정될 때 마다 View와 바인딩 되어 "자동 동기화" 해주는 듯한 느낌을 줌
당연히 여기서도 Model과 View는 서로 참조가 되지 않음.
그리고 당연히 View에서 유저에게 입력받은 데이터는 Model로 바로 가지 않고 ViewModel를 통해 전달해 주고 있음
즉, 요약하면 MVVM은 MVC와 MVP를 섞은 모습의 패턴이라고 볼 수 있을 것 같음.
MVC의 단점인 Model-View의 직접 참조를 개선하고 MVP의 단점인 View와 Presenter 사이의 높은 의존도를 끊어주는 모델이다.
각 패턴을 결합도에 따라서 분리한다면 MVC > MVP > MVVM 순으로 MVVM이 가장 결합도가 느슨하다. MVVM 쪽으로 갈 수록 설계 비용이 많이 든다는 뜻이다. 대신 결합도가 느슨하다는 것은 확장성과 유지 보수성이 높다는 뜻도 된다.
그렇기에 프로젝트의 규모가 크고 인원이 많을수록 MVVM이나 MVP를 선택하는 것이 좋은 방법이다.
어떤 디자인 패턴을 내 게임에 적용할지는 여러가지를 따져보아야 함.
따져보아야 할 것은
1.데이터의 유형(어떤 데이터들은 적용 가능한 모델이 아닐 수 있음)
2.효율적인 측면
3.개발 속도(코드량, 설계비용 등)
4.게임의 장르(기획내용)
5.복잡성(너무 코드가 복잡해지면 안하느니만 못함)
결론:
1.일단 MVP는 내 게임에 적용하지 않는다.
2. MVVM이 구조적으로 가능한 모델이면 MVVM 디자인 패턴을 반드시 적용한다.
3. 2번이 불가능하면 MVC로 구현해보되 Controller가 필요없는 모델이면 M과V만 구현해본다.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=vactorman&logNo=221013790924
MVVM pattern for WPF - UI를 다루는 여러 패턴들(MVC, MVP, MVVM)
포스팅에 앞서 주의 사항 몇 가지 공지. ※ 주의 1. 이 포스팅의 내용은 지극히 개...
blog.naver.com
'게임개발 > 스터디' 카테고리의 다른 글
[스터디] ref/out 차이 (0) | 2024.05.07 |
---|---|
[스터디] 해시 테이블 자료구조 정리 (0) | 2024.05.05 |
[스터디] 제네릭 Generic 이란? (0) | 2024.04.17 |
[스터디] 람다 함수(익명 함수)란? (0) | 2024.04.16 |
[스터디] 액션 Action 함수란? (0) | 2024.04.15 |