장고(Django) - MVC패턴과 MTV패턴
MVC패턴과 MTV패턴
웹 개발을 공부하시는 분이라면 MVC패턴에 대해 한 번쯤은 들어보셨을 겁니다.
MVC(Model-View-Controller)는 *디자인 패턴중의 하나로 프로젝트의 구성 요소를 Model(모델), View(뷰), Controller(컨트롤러) 세 가지로 역할에 따라 구분하는 패턴입니다.
MTV(Model-Template-View)는 Model(모델), Template(템플릿), View(뷰)로 MVC에 대응되는 장고의 디자인 패턴입니다.
이 글에서는 MVC패턴이 무엇인지, MTV패턴은 무엇이 다른지 다뤄보겠습니다.
(*디자인 패턴 : 효율적으로 코드를 작성하기 위한 코딩 규칙 or 프로젝트 구조 정도로 이해하시면 됩니다.)
MVC 패턴이란?
상술했듯이 MVC는 디자인 패턴 중 하나로 구성 요소를 Model, View, Controller로 구분하는 패턴입니다.
중요한 점은 각각의 구성 요소가 다른 요소들에게 영향을 미치지 않아야 한다는 것 입니다.(구성 요소간의 간섭 없이 각자의 역할에만 충실해야 한다는 패턴입니다.)
각 구성요소가 하는 역할은 다음과 같습니다.
Model(모델)
- 데이터를 가지고 있으며, 데이터를 처리하는 로직 또한 가지고 있습니다.
View(뷰)
- 화면에 요청에 대한 결과물을 보여주는 역할을 합니다. 유저와 어플리케이션 간의 인터페이스 라고 생각할 수도 있습니다.
Controller(컨트롤러)
- 모델과 뷰를 이어주는 역할을 한다고 보시면 됩니다. 요청에 따라 모델에게 적절한 로직을 가동하도록 알려주고 모델이 응답하면 그 응답을 뷰에 전달하는 역할입니다.
그림으로 한번 살펴봅시다.
1. 유저가 컨트롤러에 요청을 보냅니다.(예시 : 뷰에 있는 Submit 버튼을 누른다)
2. 컨트롤러가 모델에 요청사항대로 데이터를 수정할 것을 지시합니다.
3. 모델은 지시받은대로 데이터를 수정하고 컨트롤러에게 완료되었음을 알려줍니다.
4. 컨트롤러는 수정된 데이터를 토대로 표시할 뷰를 결정하고 화면을 출력할 것을 지시합니다.
5. 뷰는 지시받은대로 화면을 출력합니다.
MVC패턴의 장점과 한계
MVC패턴은 각각의 구성 요소가 분리되어 본연의 역할에만 충실한 구조이므로 유연성이 높고 유지보수가 용이하며 개발자와 디자이너의 작업 영역을 분리할 수 있다는 장점이 있습니다.
하지만 프로젝트의 규모가 커질수록 컨트롤러가 비대화되고 모델과 뷰의 의존성을 완벽히 분리할 수가 없기 때문에 유지보수가 점점 어려워진다는 단점이 있습니다. 이를 보완한 디자인 패턴도 여럿 있으니(MVP, MVVM 등) 관심있으신 분들은 구글링을 한번 해 보시길 권해드립니다.
MTV 패턴
MTV 패턴은 장고의 디자인 패턴입니다.
(간혹 MVT라고 부르는 분들도 계시지만 저는 MVC에 대응시키기 편하게 MTV를 사용합니다.)
MTV 패턴은 명칭이 조금 다를 뿐이지 기본적인 골자는 MVC 패턴과 동일합니다.
그렇다면 왜 굳이 장고가 MTV라는 디자인 패턴을 사용할까요?
이는 MTV 패턴만의 특징이 있기 때문입니다.
Model(모델)
- MVC 패턴의 모델에 대응되며 DB에 저장되는 데이터를 의미합니다. 모델은 클래스로 정의되며 하나의 클래스가 하나의 DB Table입니다.
원래 DB를 조작하기 위해선 SQL을 다룰 줄 알아야 하지만 장고는 ORM(Object Relational Mapping)기능을 지원하기 때문에 파이썬 코드로 DB를 조작할 수 있습니다.(ORM에 대해서는 추후 다루겠습니다.)
Template(템플릿)
- MVC 패턴의 뷰에 대응되며 유저에게 보여지는 화면을 의미합니다. 장고는 뷰에서 로직을 처리한 후 html 파일을 context와 함께 렌더링하는데 이 때의 html 파일을 템플릿이라 칭합니다.
장고는 자체적인 Django Template 문법을 지원하며 이 문법 덕분에 html 파일 내에서 context로 받은 데이터를 활용할 수 있습니다.
View(뷰)
- MVC 패턴의 컨트롤러에 대응되며 요청에 따라 적절한 로직을 수행하여 결과를 템플릿으로 렌더링하며 응답합니다. 다만 항상 템플릿을 렌더링 하는 것은 아니고 백엔드에서 데이터만 주고 받는 경우도 있습니다.
여기에 장고는 URLConf(URL 설계)라는 단계가 하나 더 있습니다.
URL 패턴을 정의하여 해당 URL과 뷰를 매핑하는 단계라고 생각하시면 됩니다.
from django.urls import path
from . import views
app_name = 'project'
urlpatterns = [
path('', views.HomeView.as_view(), name='home'),
path('login/', views.LoginView.as_view(), name='login'),
]
이와 같이 path함수를 이용해 URL을 뷰와 손쉽게 매핑시킬 수 있습니다.
그림으로 정리하면 아래와 같습니다.
1. 유저가 특정 url로 요청을 보냅니다.
2. urlConf를 통해 해당 url과 매핑된 뷰를 호출합니다.
3. 호출된 뷰는 요청에 따라 적절한 로직을 수행하며 그 과정에서 모델에게 CRUD를 지시합니다.
4. 모델은 ORM을 통해 DB와 소통하며 CRUD를 수행합니다.
5. 그 후 뷰는 지정된 템플릿을 렌더링하고
6. 최종 결과를 응답으로 반환합니다.