UI 구조 공부 (MVC, MVP, MVVM)

박지예·2026년 6월 22일

공부2026

목록 보기
4/20

UI 아키텍처 패턴 중 "UI 코드와 로직 코드를 분리하자" 는 목표를 가지고 있는 MVC, MVP, MVVM 에 대하여 알아보자.

사실 UI 아키텍처에 따라서 맞춰야해!!!! 라는 느낌으로 구조를 짜진 않는데, 알고보니 이미 사용하고 있었다. 그러니 이왕이면 아키텍쳐 공부 후 멋있게 사용하고 있다고 말해버리기~


MVC - Model View Controller

가장 오래된 패턴. Controller가 중간에서 Model과 View 를 연결한다.

Model 이 해당 View를 직접 알고 있다. (Observer 패턴으로 갱신). View도 Model 을 직접 읽을 수 있다. Controller 는 "사용자 입력 -> Model 업데이트" 만 담당한다.

문제점

Model <-> View 사이의 의존성이 생겨서 테스트가 어렵고, View가 복잡해질 수 록 Model 과 결합도가 높아진다.

예를 들어, 플레이어의 HP 를 표시하는 시스템ㅇ을 MVC 로 구현했다고 가정하자.

// Model
public class PlayerModel
{
    public int HP { get; private set; } = 100;
    private PlayerHPView _view;  // ⚠️ Model이 View를 직접 참조!

    public PlayerModel(PlayerHPView view)
    {
        _view = view;
    }

    public void TakeDamage(int damage)
    {
        HP -= damage;
        _view.UpdateHP(HP);  // ⚠️ Model이 View를 직접 호출
    }
}

// View
public class PlayerHPView : MonoBehaviour
{
    public Text hpText;
    private PlayerModel _model;  // ⚠️ View도 Model을 직접 참조!

    void Start()
    {
        _model = new PlayerModel(this);  // 서로가 서로를 물고 있음
    }

    public void UpdateHP(int hp)
    {
        hpText.text = $"HP: {hp}";
    }

    void OnClick_AttackSelf()
    {
        _model.TakeDamage(10);
    }
}

여기서 Player의 HP를 테스트 하고 싶다면 PlayerModel을 생성할 때 PlayerHPView도 생성해야 한다. 그러나

[Test]
public void TakeDamage_Should_Reduce_HP()
{
    // PlayerModel을 만들려면 PlayerHPView가 필요
    // PlayerHPView는 MonoBehaviour → Unity 씬이 필요
    // Unity 씬은 PlayMode 테스트 환경이 필요...
    
    var view = new PlayerHPView(); // ❌ MonoBehaviour라 new 불가
    var model = new PlayerModel(view); // ❌ 결국 테스트 불가
    
    model.TakeDamage(10);
    Assert.AreEqual(90, model.HP);
}

MonoBehaviour 인 View를 위해 과하게 test 환경을 셋팅해야 하는 문제가 있다. (과한 의존성)

위를 보완하기 위해 나온 패턴이 뒤에 설명할 MVP와 MVVM 이다.


MVP - Model View Presenter

View와 Model을 완전히 분리하고, Presenter가 모든 걸 중재한다.

View는 interface 만 갖고, 실제 구현을 Presenter 에 위임한다. Presenter는 View를 인터페이스로만 알기 때문에 View 없이 Presenter만 단독 테스트가 가능하다.

문제점

View마다 Presenter 를 하나씩 만들어야 해서 코드가 많아진다. Presenter가 비대해지기 쉽다.

MVVM - Model View ViewModel

view가 ViewModel의 데이터에 자동으로 바인딩되어 동기화 된다.

ViewModel은 View를 전혀 모른다. 대신 View가 ViewModel의 속성을 바인딩(구독) 해서 값이 바뀌면 자동으로 화면이 갱신된다.

Unity로 게임개발할 때 주로 ReactiveProperty 를 사용해서 바인딩 했다.


그 외에도 다양한 UI 바인딩이 많은데, 인터넷에서 찾아보니까 Unity6의 UIToolkit 을 네이티브로 지원하고 있단다. 나중에 한번 공부해봐야겠다.

profile
게임 클라이언트 개발자

0개의 댓글