MVC 아키텍쳐

박준수·2023년 4월 17일
0

MVC 아키텍쳐란?

  • UI가 있는 소프트웨어를 만들다 보니 아주 오래전부터 개발자들은,

MVC, 즉 Model, View, Controller라는 영역으로 나누면 딱 좋다라는 것을 알게 되었습니다.

View (화면)

  • UI에서 가장 중요한 것은 역시 화면이죠.

  • 첫번째는 우리가 제일 쉽게 이해할 수 있는 부분! 바로 이 View입니다.

  • 웹 프론트에서는 대개 최종적으로 HTML과 CSS로 만들어지는 결과물을 의미합니다.

  • V(View)는 html, css로 만들어진 말 그대로의 화면을 말합니다.

Model (데이터)

  • 소프트웨어가 멈춰있는 화면만 있으면 디자인과 다를 게 없겠죠.

  • 화면에의 어딘가는 실제의 데이터가 반영이 되어 나타나야 합니다.

  • 이러한 데이터를 주관하는 영역을 Model이라고 부릅니다.

  • 이 Model의 범주는 아키텍쳐에 따라 달라집니다.

  • javascript의 Object일 수도 있고,서버의 API로 받는 데이터일수도 있고,서버에 있는 DB일 수도 있습니다.

  • 어쨌든 화면이 아닌 소프트웨어가 다뤄야할 중요한 데이터 영역입니다.

  • M(Model)은 ajax를 통해 받은 데이터와 그 데이터를 통해 변경될 수 있는 상태를 말합니다.

    • 상태란?
    • 프로그래밍에서의 상태는 데이터로 표현합니다.
    • 컴퓨터 프로그램에서 상태란 시간이 지남에 따라서 변할 수 있는 데이터입니다.
    • 프론트엔드에서 상태란 웹 애플리케이션을 구성하는 데이터라고 할 수 있습니다.
    • 이러한 데이터는 웹 애플리케이션의 사용자에 의해 시간에 따라서 생성되고, 읽히고, 수정되고, 삭제될 수 있습니다.(CRUD)
    • UI에 영향을 줄 수 있는 모든 데이터입니다.

Controller (컨트롤러)

UI 소프트웨어의 본질은 단순합니다. 우선 데이터를 화면에 그립니다. 그리고 우리가 어떤 동작을 취하면 데이터가 바뀝니다. 데이터가 바뀌면 다시 화면이 바뀌겠죠.

  • 이렇게 Model의 데이터를 받아서 화면에 그리고, 화면으로 부터 사용자의 동작을 받아서 Model을 변경합니다.
  • 이러한 Model과 View사이의 중간 역할을 하는 것을 Controller라고 합니다.
  • MVC가 이렇게 나눠진 이유는,

화면을 다루는 문제와 데이터를 다루는 문제의 성격이 달라서 분리하고 싶고Model과 View간의 의존관계를 최소화 해서 화면의 수정이 데이터수정에 영향을 미치지 않고 데이터 수정이 화면의 수정에 영향을 미치지 않고자 함입니다.

  • C(Controller)는 javascript가 View에서 호출되는 이벤트를 통해 서버에 데이터를 전달하고, 다시 전달받은 데이터로 Model을 변경해주는 역할을 합니다.

MVC 아키텍쳐는 왜 사용할까?

  • MVC(Model-View-Controller) 아키텍처는 관심사를 명확하게 분리하고 코드 유지 관리 및 재사용성을 개선하며 개발자 간의 효율적인 협업을 가능하게 하기 때문에 프런트엔드 개발에서 일반적으로 사용됩니다.

관심사 분리:

  • MVC 아키텍처는 애플리케이션 로직을 모델, 뷰 및 컨트롤러의 세 가지 구성 요소로 분리합니다.
  • 모델은 데이터와 비즈니스 로직을 나타내고 뷰는 사용자 인터페이스를 처리하며 컨트롤러는 모델과 뷰 간의 통신을 관리합니다.
  • 이러한 분리를 통해 코드를 더 잘 구성하고 관리할 수 있으므로 시간이 지남에 따라 더 쉽게 이해, 수정 및 유지 관리할 수 있습니다.

코드 유지 관리 및 재사용 가능성:

  • MVC의 모듈식 구조는 코드 재사용 및 유지 관리를 촉진합니다.
  • 관심사를 분리하면 각 구성 요소를 독립적으로 개발하고 테스트할 수 있으므로 다른 부분에 영향을 주지 않고 응용 프로그램의 특정 부분을 쉽게 업데이트하거나 교체할 수 있습니다.
  • 이를 통해 유지 관리 및 확장 가능한 코드가 생성되어 버그의 위험이 줄어들고 향후 응용 프로그램을 쉽게 확장하거나 향상시킬 수 있습니다.

효율적인 협업:

  • MVC는 프런트엔드 개발자 간의 효율적인 협업을 촉진합니다.
  • 각 구성 요소의 책임이 잘 정의되어 있기 때문에 여러 개발자가 서로 발을 디딜 필요 없이 애플리케이션의 서로 다른 부분에서 동시에 작업할 수 있습니다.
  • 이를 통해 개발 워크플로를 간소화하고 생산성을 향상하며 대규모 프로젝트에서 팀워크를 촉진할 수 있습니다.

jQuery시절의 MVC 아키텍쳐

웹 프론트엔드라는 개념도 없던 웹 서비스 초창기 시절의 MVC는

  • 데이터베이스를 Model로 취급하고
  • HTML과 CSS, 그리고 javascript까지 포함한 클라이언트 영역을 View
  • 그리고 가운데서 라우터를 통해 데이터를 처리하고 새로운 HTML을 만들어서 보여주는 백엔드 영역을 Controller라고 취급했습니다.

그러다가 프론트엔드의 역할이 추가되고 특히 ajax라는 기술이 만들어지면서 이제는 HTML을 서버에서 직접 만들 필요가 없게 되었습니다.

  • ajax로 부터 받는 데이터를 Model로 취급합니다.
  • HTML과 CSS로 만들어지는 화면을 View로 취급합니다.
  • javascript가 중간에서 서버의 데이터를 받아서 화면을 바꾸고 이벤트를 처리해서 서버에 데이터를 전달하는 Controller의 역할을 수행하게 됩니다.

MVC 아키텍쳐의 예시 상황

https://velog.velcdn.com/images%2Fluna238%2Fpost%2Fbac0c6d6-2689-4376-a086-d40f7d820288%2Fimage.png

  • 브라우저에서 이 버튼을 클릭했을 때 일어나는 일을 생각해 봅시다.
  • 잘 구현된 버튼이라면 하나의 기능을 수행하는 이벤트가 버튼에 바인딩 되어 있을 것입니다.
  • 사용자는 브라우저의 화면에 보여지는 html과 css로 이루어진 View의 버튼을 통해 이벤트를 호출할 것입니다.
  • View에서 호출된 이벤트로 Controller가 서버에 데이터를 요청하든지 상태를 직접 변경하든지 Model을 변경합니다.
  • Model이 변경되면 View에 변경된 Model을 반영해줍니다.
  • 이 때 Model은 직접 View를 변경할 수 없고, Controller를 통해 변경해야 합니다.
  • 그래서 프론트엔드의 MVC는 View -> Controller -> Model -> Controller -> View 형태입니다.
  • Model, View, Controller는 각각의 의존관계를 가지고 있기 때문에 코드를 작성할 때, 유지보수가 쉽고 코드의 흐름을 예측할 수 있어서 원하는 부분을 찾기 수월해집니다.

MVC 아키텍쳐는 어떻게 사용할까?

첫번째 예시

// Model
let state = 0;
const $button = document.querySelector('button');

// View
const render = () => {
  document.body.innerHTML = state;
};

// Controller
const setState = newState => {
  state = newState;
  render();
};

$button.addEventListener('click', () => {
  setState(state + 1);
});
  • 사용자가 View인 button을 클릭하면 button에 바인딩된 함수가 호출되면서 setState
    가 호출된다.
  • Controller인 setState함수는 Model인 state의 값을 변경하고, render함수를 호출하는데 DOM에 직접 접근하여 View영역을 변경해준다.
  • 사용자는 View영역의 button에 접근했는데, Controller와 Model을 순차적으로 거쳐 View
    에 새로운 값이 반영되는 것을 확인할 수 있다.

두번째 예시

Model

  • 모델은 애플리케이션의 데이터 및 비즈니스 로직을 나타냅니다.
  • 필요한 데이터 조작 또는 유효성 검사를 수행할 뿐만 아니라 데이터 검색 및 저장을 담당합니다.
  • 프런트엔드 애플리케이션에서 모델은 JavaScript 개체이거나 데이터를 보유하고 데이터와 상호 작용하는 메서드를 제공하는 클래스일 수 있습니다.

class User {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  save() {
    // Code to save user data to a database or API
  }

  update() {
    // Code to update user data in the database or API
  }

  delete() {
    // Code to delete user data from the database or API
  }
}

View

  • 뷰는 사용자 인터페이스를 렌더링하고 사용자에게 데이터를 표시하는 역할을 합니다.
  • 모델에서 데이터를 수신하여 시각적으로 매력적인 방식으로 사용자에게 제공합니다.
  • 프런트엔드 애플리케이션에서 HTML, CSS 및 JavaScript를 사용하여 보기를 구현하여 사용자 인터페이스를 만들 수 있습니다.
<!-- HTML template for displaying user information -->
<div id="user-info">
  <h1 id="user-name"></h1>
  <p id="user-email"></p>
</div>
// JavaScript code to update the View with user data
function updateUserView(user) {
  document.getElementById('user-name').innerText = user.name;
  document.getElementById('user-email').innerText = user.email;
}

Controller

  • 컨트롤러는 모델과 뷰 사이의 중개자 역할을 합니다.
  • View에서 사용자 입력을 받고 그에 따라 Model을 업데이트한 다음 View를 업데이트하여 변경 사항을 반영합니다.
  • 또한 View에 의해 트리거된 모든 사용자 상호 작용 또는 이벤트를 처리합니다.
// JavaScript code for handling user interactions and updating the Model and View
class UserController {
  constructor(model, view) {
    this.model = model;
    this.view = view;
  }

  updateUser(name, email) {
    // Update the Model with new data
    this.model.name = name;
    this.model.email = email;

    // Save the updated data
    this.model.save();

    // Update the View to reflect the changes
    this.view.updateUserView(this.model);
  }
}

// Usage:
const user = new User('John', 'john@example.com');
const view = new UserView();
const controller = new UserController(user, view);

// Update user data and trigger View update
controller.updateUser('Jane', 'jane@example.com');

세번째 예시

// Model (Data)
const dataModel = {
  counter: 0
};

// View (User Interface)
const view = {
  displayCounter: function(counter) {
    document.getElementById('counter').textContent = counter;
  }
};

// Controller (Logic)
const controller = {
  incrementCounter: function() {
    dataModel.counter++;
    view.displayCounter(dataModel.counter);
  },
  
  decrementCounter: function() {
    dataModel.counter--;
    view.displayCounter(dataModel.counter);
  }
};

// Event Listeners
document.getElementById('incrementBtn').addEventListener('click', controller.incrementCounter);
document.getElementById('decrementBtn').addEventListener('click', controller.decrementCounter);
  • 'dataModel'은 애플리케이션의 데이터 또는 상태를 나타내고
  • 'view'는 사용자 인터페이스 렌더링을 담당하며
  • 'controller'는 로직을 처리하고 그에 따라 모델과 뷰를 업데이트합니다.
  • 이벤트 리스너는 HTML의 각 버튼에 연결되며 버튼을 클릭하면 컨트롤러의 메서드가 호출되어 모델과 뷰를 업데이트합니다.
  • 그러면 view가 UI에 업데이트된 카운터 값을 표시합니다.

MVC 아키텍쳐의 단점은 무엇일까?

  • jQuery로 작업을 하다보니 상당히 불편한 점을 발견하게 됩니다.
  • 데이터를 찾아서 데이터를 바꾸고 데이터를 수정하고 이벤트를 연결하고 이벤트를 수정하는 부분들에서 피곤한 반복적인 패턴이 나타난다는 것을 알게 되었습니다.
  • 서버에서 개발을 할 때에는 html이 전체적으로 렌더링으로 되다보니 {{ }}<?= ?><%= %> 와 같은 치환자로 통해 선언적으로 편하게 개발을 하는 반면 jQuery의 경우 전체 html를 갱신했다가는 번쩍거리는 화면을 맛볼 수 있으니 수정해야 할 부분을 일일히 찾아서 수정을 해줘야 했습니다.

출처

https://velog.io/@teo/프론트엔드에서-MV-아키텍쳐란-무엇인가요#프롤로그

profile
심플한 개발자를 향해 한걸음 더 (과거 블로그 : https://crablab.tistory.com/)

0개의 댓글