소프트웨어 디자인 패턴 - 4. MVU 패턴 (Model-View-Update)

2025. 1. 20. 12:15소프트웨어/디자인 패턴

MVU 패턴이란?

MVU 패턴은 애플리케이션의 상태 관리와 UI 갱신을 단순화하기 위해 설계된 패턴으로, Model, View, Update의 세 가지 구성 요소로 나뉩니다. 상태 변경 흐름이 명확하고 불변성을 유지하여 안정적이고 예측 가능한 애플리케이션을 만드는 데 적합합니다. Elm 아키텍처와 Redux와 같은 상태 관리 라이브러리에서 사용됩니다.


구성 요소

1. Model

  • 애플리케이션의 상태를 표현합니다.
  • 단순한 변수, 구조체, 또는 복잡한 객체일 수 있습니다.
  • 상태는 불변성을 유지하며, 새로운 상태를 반환하는 방식으로 갱신됩니다.

2. View

  • UI를 렌더링하는 역할을 합니다.
  • Model의 현재 상태를 기반으로 화면에 데이터를 표시합니다.

3. Update

  • 사용자 이벤트를 처리하고 새로운 상태를 반환합니다.
  • 상태 변경 로직이 포함되며, 입력 이벤트에 따라 Model을 업데이트합니다.

MVU의 특징

  1. 명확한 상태 변경 흐름:
    • 상태 변경이 Model, View, Update의 순환을 따르므로 로직이 직관적입니다.
  2. 불변성 유지:
    • 상태를 갱신할 때 기존 상태를 수정하지 않고 새로운 상태를 생성합니다.
  3. 디버깅과 예측 가능성 증가:
    • 상태 변경이 불변성을 따르므로 상태 추적 및 디버깅이 용이합니다.

장점

  1. 예측 가능한 상태 관리:
    • 상태 변경의 흐름이 명확하여 디버깅이 쉽습니다.
  2. 불변성으로 안정성 강화:
    • 기존 상태를 보호하여 부작용을 방지합니다.
  3. 테스트 가능성:
    • Update 로직과 상태 변화를 독립적으로 테스트할 수 있습니다.

단점

  1. 초기 학습 곡선:
    • MVU에 익숙하지 않은 개발자에게는 새로운 상태 관리 방식이 어렵게 느껴질 수 있습니다.
  2. 성능 문제:
    • 상태 변경 후 View를 다시 렌더링하므로, 최적화가 필요할 수 있습니다.

적용 예시

1. 카운터 애플리케이션

  • Model: 현재 카운트 값을 저장.
  • View: 카운트 값을 화면에 표시하고 증가/감소 버튼 제공.
  • Update: 버튼 클릭 이벤트에 따라 카운트 값을 증가/감소.

2. Todo 리스트 애플리케이션

  • Model: 할 일 목록.
  • View: 목록을 화면에 표시하고 추가/삭제 버튼 제공.
  • Update: 버튼 클릭 시 목록에 항목 추가 또는 삭제.

3. 계산기 애플리케이션

  • Model: 현재 입력 값과 결과 값.
  • View: 입력 필드와 결과를 화면에 표시.
  • Update: 버튼 클릭 이벤트에 따라 계산 결과 갱신.

C++ 예제 코드: 간단한 카운터 애플리케이션

#include <iostream>
#include <functional>
using namespace std;

// Model: 애플리케이션의 상태
struct CounterModel {
    int count;
};

// View: 사용자 인터페이스
void render(const CounterModel& model) {
    system("clear"); // 화면 지우기 (Linux/Unix 기준, Windows 사용자는 system("cls") 사용 가능) 
    cout << "Counter: " << model.count << endl;
    cout << "1. Increment" << endl;
    cout << "2. Decrement" << endl;
    cout << "3. Exit" << endl;
    cout << "Choose an option: ";
}

// Update: 상태를 갱신하는 함수
CounterModel update(const CounterModel& model, int action) {
    CounterModel newModel = model; // 기존 상태를 복사

    if (action == 1) {
        newModel.count++;
    } else if (action == 2) {
        newModel.count--;
    }

    return newModel; // 새로운 상태 반환
}

// Main: 애플리케이션 실행
int main() {
    CounterModel model = {0}; // 초기 상태

    while (true) {
        render(model); // View 렌더링

        int action;
        cin >> action;

        if (action == 3) {
            break; // 애플리케이션 종료
        }

        model = update(model, action); // 상태 갱신
    }

    return 0;
}

코드 설명

Model

  • CounterModel: 현재 카운트를 저장하는 구조체.

View

  • render: Model의 현재 상태를 기반으로 UI를 렌더링.

Update

  • update: 사용자의 입력(action)에 따라 새로운 상태를 반환.

실행 결과 예시

Counter: 0
1. Increment
2. Decrement
3. Exit
Choose an option: 1

Counter: 1
1. Increment
2. Decrement
3. Exit
Choose an option: 2

Counter: 0
1. Increment
2. Decrement
3. Exit
Choose an option: 3

MVU 패턴 요약

  1. Model은 애플리케이션의 상태를 나타냅니다.
  2. View는 상태를 기반으로 UI를 렌더링합니다.
  3. Update는 이벤트를 처리하고 새로운 상태를 반환합니다.

MVU 패턴은 상태 관리가 중요하고, 예측 가능한 애플리케이션 로직이 필요한 프로젝트에 적합합니다.