본문 바로가기
Programming Language/Javascript

[Javascript] MVC, MVP, MVVM 간단히 비교하기

by ggyongi 2025. 3. 6.

MVC

전통적인 방식

뷰에서 모델을 직접 참고함 -> 뷰에서 렌더링 시 모델의 정보를 사용

컨트롤러는 뷰로부터 이벤트를 받아서 모델을 업데이트 해주는 역할

// Model (데이터 및 로직 관리)
class Model {
    constructor() {
        this.text = "Hello, MVC!";
    }
    updateText(newText) {
        this.text = newText;
    }
}

// View (UI, Model 직접 참조)
class View {
    constructor(model) {
        this.model = model;  // ✅ View가 Model을 직접 참조
        this.button = document.createElement("button");
        this.button.textContent = "Change Text";
        this.label = document.createElement("p");
        document.body.append(this.label, this.button);
    }

    render() {
        this.label.textContent = this.model.text; // ✅ View가 Model의 데이터를 직접 가져옴
    }
}

// Controller (이벤트 처리)
class Controller {
    constructor(model, view) {
        this.model = model;
        this.view = view;

        this.view.button.addEventListener("click", () => {
            this.model.updateText("MVC Updated!");
            this.view.render();  // ✅ View가 Model을 직접 참조하고 있기 때문에 render 호출
        });

        this.view.render(); // 초기 렌더링
    }
}

// 실행
const app = new Controller(new Model(), new View(new Model()));

 

MVP

모델과 뷰의 연결을 완전히 끊음

프레젠터가 모델도 업데이트하고 뷰가 사용할 데이터를 직접 업데이트

// Model
class Model {
    constructor() {
        this.text = "Hello, MVP!";
    }
    updateText(newText) {
        this.text = newText;
    }
}

// View (Model을 참조하지 않음)
class View {
    constructor() {
        this.button = document.createElement("button");
        this.button.textContent = "Change Text";
        this.label = document.createElement("p");
        document.body.append(this.label, this.button);
    }

    setPresenter(presenter) {
        this.presenter = presenter;
        this.button.addEventListener("click", () => this.presenter.onButtonClick());
    }

    updateText(text) {
        this.label.textContent = text;
    }
}

// Presenter (중재 역할)
class Presenter {
    constructor(model, view) {
        this.model = model;
        this.view = view;
        this.view.setPresenter(this);
        this.view.updateText(this.model.text);
    }

    onButtonClick() {
        this.model.updateText("MVP Updated!");
        this.view.updateText(this.model.text);
    }
}

// 실행
const app = new Presenter(new Model(), new View());

 

 

MVVM -> 리액트에서 사용되는 패턴

MVP와 유사하나 VM(뷰모델)은 데이터를 그저 담는 역할(store 역할일뿐.. 뷰의 업데이트는 상관안함)

VM은 이벤트를 받아 모델을 업데이트하고 그 새로운 데이터를 가공하여 별개로 갖고 있음

뷰는 VM에 있는 별개의 뷰를 참조하며 그 데이터를 사용하여 뷰 업데이트. 즉 VM을 구독함.

// Model (데이터)
class Model {
    constructor() {
        this.text = "Hello, MVVM!";
    }
    updateText(newText) {
        this.text = newText;
    }
}

// ViewModel (Model을 View에 연결)
class ViewModel {
    constructor(model) {
        this.model = model;
        this.text = this.model.text;  // ✅ ViewModel이 Model의 데이터를 가공하여 저장
    }

    updateText() {
        this.model.updateText("MVVM Updated!");
        this.text = this.model.text;  // ✅ ViewModel이 상태 변경을 관리
    }
}

// View (UI, ViewModel을 사용)
class View {
    constructor(viewModel) {
        this.viewModel = viewModel;
        this.button = document.createElement("button");
        this.button.textContent = "Change Text";
        this.label = document.createElement("p");
        document.body.append(this.label, this.button);

        this.button.addEventListener("click", () => {
            this.viewModel.updateText();
            this.render();
        });

        this.render();
    }

    render() {
        this.label.textContent = this.viewModel.text;  // ✅ View는 ViewModel의 데이터를 사용하여 UI 업데이트
    }
}

// 실행
const model = new Model();
const viewModel = new ViewModel(model);
const view = new View(viewModel);

📘 비전공자 개발자 취업 성공기 시리즈

개발자가 되고 싶었던 한 비전공자의 1년 4개월 이야기
막막했던 시작부터 좌절, 그리고 합격까지의 여정을 기록했습니다

 

비전공자 네카라 신입 취업 노하우

시행착오 끝에 얻어낸 취업 노하우가 모두 담긴 전자책!

kmong.com

댓글