MVC 패턴을 알아보기 전에 MVC 패턴의 각 구성 요소와 역할을 자세히 살펴보자
MVC 패턴에는 M(Mdoel), V(View), C(Controller)가 있다.
Model(모델)
-
좁은 정의의 관점에서는 Model(주로 Entity 클래스)은 데이터만 담당하며 비즈니스 로직은 Service 계층에 위치하며, 이 계층은 Model과 상호작용하여 데이터를 조작하거나 규칙을 적용한다.
하지만 넓은 범위의 해서은 단순히 데이터 구조만을 나타내는 것이 아니라, 그 데이터와 관련된 비즈니스 로직도 포함된다. 이 방식은 DDD(도메인 주도 설계)와 더 가까우며, Model 자체가 비즈니스 로직을 수행하는 메서드를 가질 수 있다.
-
Entity에서는 Soc(관심사의 분리)원칙을 가진 것이 일반적으로 좋은 설계 원칙으로 여겨지기 때문에 비즈니스 로직은 Entity가 아니라 Service 계층에 위치시켜서 분리 시킬 수 있다.
Model에서 비즈니스 로직을 작성하듯이 Entity와 Service가 분리된 구조로 생각하는 것이 맞다. Entity는 순수한 데이터 구조로 남아있고, Service는 그 데이터를 기반으로 비즈니스 규칙을 적용하는 곳이기 때문이다. 정리하면, Entity와 Service를 분리한 것은 Model에서 비즈니스 로직을 작성하는 것과는 다른 개념이지만, 두 개념 간의 상호작용은 비슷하다고 볼 수 있다.
Model의 주요 역할
- 데이터베이스와의 상호작용
- 비즈니스 규칙 적용
- 데이터 상태 관리
- 데이터 유효성 검증
Model의 특징
- View와 Controller에 종속되지 않는다.
- 재사용 가능한 형태로 설계한다.
- 변경 사항을 Observer 패턴으로 View에 통지가 가능하다.
Observer 패턴이란 객체 지향 설계에서 사용되는 행동 디자인 패턴 중 하나로, 상태 변화를 관찰하는 객체들이 그 변화를 감지하고 자동으로 알림을 받도록 하는 패턴이다. 즉, 한 객체의 상태가 변경되면 그 객체와 연관된 다른 객체들에게 그 변화를 자동으로 통지하는 방식이다.
(Observer 패턴에 대해서는 다른 글로 작성을 해보도록 하겠다)
View(뷰)
- View는 사용자에게 데이터를 표시하고, 사용자로부터 입력 받는 역할을 담당하는 계층이다.
- 이 계층은 UI(User Interface)를 제공하며, 사용자가 애플리케이션과 상호작용할 수 있는 방식으로 데이터를 표현한다. View는 주로 화면에 출력할 데이터와 UI 요소의 디자인을 다룬다.
- 중요한 점은 View는 직접적으로 비즈니스 로직이나 데이터베이스와 연결되지 않는다는 것이다. 비즈니스 로직은 Controller와 Model이 담당하고, View는 오직 그 데이터를 표시하는 역할만 수행한다.
View의 주요 역할
- 모델의 데이터를 시각적으로 표현한다. (이때 View는 데이터를 직접 처리하지 않고, Controller로부터 전달된 데이터를 사용한다.)
- 사용자에게 정보를 표시한다.
- 사용자 입력 인터페이스를 제공한다. (View는 사용자가 버튼을 클릭하거나 폼에 입력하는 것과 같은 상호작용을 수집하고, 그 데이터를 Controller로 전달한다.)
View의 특징
- 모델의 정보를 따로 저장하지 않는다.
- 모델이나 컨트롤러와 독립적이다.
- 동일한 모델의 다양한 표현 방식 가능하다.
View의 동작 흐름
- Controller에서 처리된 데이터가 Model을 통해 View로 전달된다.
- View는 받은 데이터를 UI 요소를 통해 표시한다. 예를 들어, 웹 애플리케이션에는 HTML, CSS, JavaScript 등을 사용하여 데이터를 화면에 렌더링한다.
- 사용자가 입력하거나 상호작용(예: 버튼 클릭, 폼 입력 등)을 하면, 그 입력을 Controller에게 전달하여 애플리케이션이 다음 동작을 수행할 수 있도록 한다.
예시)
1. Controller가 Model에 데이터를 담아 View로 전달: Controller에서 특정 View(예: Thymeleaf 템플릿)를 호출하고, 그 View에 렌더링할 데이터를 Model 객체에 담아 넘긴다.
2. View에서 데이터 렌더링: View는 해당 데이터를 사용하여 사용자에게 보여줄 HTML 페이지를 생성한다.
SpringBoot에서 View의 역할
- 주로 Thymeleaf, JSP, FreeMarker, Mustache 같은 템플릿 엔진을 사용하여 View를 처리한다.
- 템플릿 엔진들은 서버에서 HTML 파일을 동적으로 생성하고, 필요한 데이터는 Controller를 통해 전달받는다.
View의 종류
Server-side View
(서버에서 데이터를 받아 UI를 렌더링한 후, 완성된 HTML 페이지를 클라이언트에게 반환하는 방식)
- JSP(Java Server Pages): Java 기반의 서버 측 템플릿 기술로, 데이터를 받아 HTML 코드에 동적으로 삽입하여 클라이언트에게 반환한다.
- Thymelaef: HTML 파일을 기반으로 렌더링을 진행한다.
- FreeMarker, Mustache: Thymeleaf와 같이 서버 사이드 템플릿 엔진
Client-side View
(클라이언트에서 데이터를 처리하고, 동적으로 HTML을 생성하여 화면에 표시하는 방식)
- JavaScript 프레임워크( React, Angular, Vue): 클라이언트 사이드에서 API로 데이터를 받아, JavaScript를 통해 동적으로 UI를 생성한다.
- 예를 들어, React는 프론트엔드에서 동적으로 데이터를 받아 화면을 갱신하는 방식으로 작동한다. 이때 데이터는 주로 REST API를 통해 백엔드로부터 받아온다.
View의 유형별 장단점
장점:
- 서버 사이드 렌더링의 경우 초기 로딩 속도가 빠르다.
- 서버에서 데이터를 렌더링하고 완성된 페이지를 클라이언트에 전달하기 때문에, 데이터 노출의 위험이 적다.
- 서버에서 동적으로 데이터를 받아 HTML에 쉽게 결합할 수 있다.
단점:
- 클라이언트 사이드와 서버 사이드를 통합할 때 복잡도가 높아질 수 있다.
- 유연성 부족: 클라이언트 사이드에서 즉각적인 화면 갱신이 필요한 경우, 서버에서 매번 데이터를 받아오는 방식은 비효율적일 수 있다.
View는 애플리케이션에서 UI와 데이터를 연결하는 중요한 역할을 한다. SpringBoot와 같은 프레임워크에서는 주로 서버 사이드 템플릿 엔진을 사용하여 View를 처리하며, 이를 통해 사용자는 웹페이지에서 데이터를 직관적으로 확인하고 상호작용할 수 있다.
Controller(컨트롤러)
Controller는 사용자의 요청을 처리하고, Model과 View를 연결하는 역할을 한다. 사용자로부터 입력을 받고, 비즈니스 로직을 실행한 뒤 응답을 반환하는 것이 Controller의 주요 역할이다. 즉, Model과 View 사이의 중개자 역할을 한다.
Controller의 주요 역할
- 사용자 입력 처리: HTTP 요청이 들어오면, URL, 요청 메서드(GET, POST 등)에 따라 해당 요청을 처리할 핸들러 메서드를 호출한다.(클라이언트로부터 들어오는 모든 요청을 최초로 받아서 처리하는 부분, URL 라우팅 처리, 요청 파라미터 추출 및 검증, 폼 데이터 또는 JSON 데이터 파싱, 사용자 인증/인가 확인)
- Model 업데이트 요청: 비즈니스 로직 처리를 위해 모델과 상호작용한다.(서비스 계층 호출, 트랜잭션 관리, 예외 처리, 처리 결과 검증)
- View 선택 및 데이터 전달(데이터와 View 연결): 처리된 경과를 적절한 뷰에 전달하고 선택(적절한 뷰 템플릿 선택, 뷰에 필요한 데이터 전달, 뷰 렌더링 방식 변경(JSON, HTML 등)
전체 흐름 제어: 전체 애플리케이션의 흐름을 제어하고 조정(사용자 세션 관리. 에러 처리 및 예외 처리, 페이지 흐름 제어, 리다이렉션 처리)
Controller의 특징
- 사용자 요청 처리
- View 또는 데이터 반환
- 비즈니스 로직과의 분리
- 유효성 검사
- 예외 처리
- 요청 매개변수 처리
SpringBoot에서 Controller
스프링부트에서는 @Controller나 @RestController 어노테이션을 사용하여 Controller 클래스를 정의한다.
1. @Controller
- 주로 HTML 같은 View를 반환하는 경우 사용된다.
- 이 경우, 템플릿 엔진을 사용하여 View를 렌더링하고, 화면을 사용자에게 제공한다.
예시) HTML 파일(View) 파일을 반환하고, 객체를 HTML에 렌더링하여 사용자에게 보여준다.
2. @RestController
- 주로 JSON 또는 XML 데이터를 반환할 때 사용된다. REST API를 구축할 때 많이 사용되며, 클라이언트가 웹 브라우저가 아닌 다른 시스템 일 때 주로 사용된다.
- @RestController는 자동으로 @ResponseBody를 적용하여, 메서드가 반환하는 데이터를 View가 아닌 JSON 형식의 응답으로 전송된다.
Controller의 장점
- 유연한 라우팅: 클라이언트로부터의 다양한 요청을 각기 다른 메서드와 쉽게 연결할 수 있다.
- 명확한 역할 분리: 비즈니스 로직을 Service 계층에 위임하고, 요청과 응답 처리에 집중할 수 있다.
- 확장성: 클라이언트와 서버 간의 요청-응답 구조가 명확하여 유지보수가 용이하고, 새로운 기능 추가 시에도 확장이 쉽다.
Controller는 사용자의 요청을 받아들여 서비스 계층에 작업을 위임하고, 그 결과를 응답으로 반환하는 역할을 담당합니다. Spring에서는 RESTful API 구현 시 @RestController를, 뷰 반환이 필요한 경우 @Controller를 주로 사용하며, 비즈니스 로직을 담당하는 Service와의 책임 분리가 잘 이루어지도록 설계합니다.
결론적으로 MVC 패턴의 전체적인 흐름은 사용자가 요청을 보내면 Controller가 이를 처리하고, Model에서 필요한 데이터를 가져와 비즈니스 로직을 처리한 후, 결과를 View에 전달해 사용자에게 출력하는 구조입니다.