MVC란
MVC 패턴이란 model, view, controller의 약자로 소프트웨어 디자인 패턴이다.
개발할 때, 3가지 형태로 나누어 개발하는 방법론이다.
비지니스 처리 로직과 사용자 인터페이스 요소들을 분리시켜 서로 영향없이 개발하기 수월하다는 장점이 있다.
Model
Model은 시스템의 비지니스 로직과 데이터를 관리하는 부분이다.
비지니스 로직: 프로그램이 수행해야 할 핵심적인 업무 처리이다. 예를 들어, 상품 주문 처리 시스템이라면 Model은 주문을 저장하고, 재고를 감소시키며, 결제 정보를 기록하는 등의 역할을 한다.
데이터 처리: Model은 데이터베이스와의 상호작용을 통해 데이터를 저장, 갱신, 삭제, 조회 등의 작업을 수행한다. 여기서는 데이터베이스와의 직접적인 통신을 담당하는 DAO 혹은 Repository를 통해 DB와 통신하는 구조로 구현되는 경우가 많다.
Model의 특징
- Model은 독립적이어야 하며, View나 Controller에 대한 정보를 가지면 안된다.
- Model에서 데이터가 변경되면, 해당 변경 사항을 통지할 수 있는 메커니즘을 갖추어야 한다. 예를 들어, 이벤트 리스너 패턴을 활용하여 데이터 변경 시 View에 알릴 수 있다.
View
View는 사용자가 데이터를 어떻게 볼지를 정의하는 역할이다. 실제 사용자 인터페이스를 담당하며 html, css, js와 같은 기술을 활용하여 데이터를 시각적으로 표현한다.
view는 model의 데이터를 직접적으로 저장하지 않으며 오직 보여주는 역할만 수행한다. 이때, View는 Controller가 전달한 데이터를 기반으로 화면에 출력한다.
View의 특징
- Model과 Controller에 대해 알 필요가 없다. View는 Contoller로부터 맏은 데이터를 기반으로 동작하므로, UI와 관련된 변경 사항이 발생해도 Model과 Controller에는 영향을 미치지 않는다.
- MVC 패턴에서는 View를 다수 정의할 수있으며, 같은 데이터를 여러 View에서 재사용할 수 있다. 예를 들어, 모바일용 View와 데스크탑용 View가 다르게 구현될 수 있다.
Controller
Controller는 사용자의 요청을 처리하고, Model과 View 사이의 데이터를 연결 및 제어하는 중개자 역할을 한다.
- 요청처리: 사용자가 페이지를 요청하면 Controller는 이 요청을 받는다.
- 비지니스 로직 처리: 요청을 받은 후Controller는 Model을 호출하여 데이터를 처리하거나 조회한다. 만약 데이터를 처리해야 한다면, Model을 통해 해당 로직을 수행한다.
- View로 데이터 전달: Model에서 처리된 데이터를 기반으로, 적절한 View에 데이터를 전달하여 사용자에게 응답한다.
사용자가 Controller를 사용하게 되면 Controller는 Model을 통해 데이터를 가져오고, 받아온 데이터를 통해 View에서 시각적인 부분을 제어하여 사용자에게 데이터를 보여준다.
1. 사용자의 Request을 Controller가 받는다.
2. Controller는 Service에서 비즈니스 로직을 처리한 후 결과를 Model에 담는다.
3. Model에 저장된 결과를 바탕으로 시각적 요소 출력을 담당하는 View를 제어하여 사용자에게 전달한다.
Spring MVC
spring MVC는 Java 기반의 프레임워크로, MVC 패턴을 구현한 대표적인 프레임워크이다. Spring MVC는 복잡한 웹 애플리케이션을 간단하게 만들 수 있도록 다양한 구성 요소를 제공한다.
DisPatcherServlet
DispatcherServlet은 Spring MVC에서 Front Controller 역할을 수행하는 핵심 구성 요소이다.
사용자의 모든 요청은 먼저 DispatcherServlet을 통해 처리 된다.
DispatcherServlet은 요청을 분석하고, 어떤 Controller가 해당 요청을 처리할지 결정한다.
또한, DispatcherServlet은 요텅에 적절한 View를 반환하는 일련의 흐름을 관리한다.
직접 만든 MVC 프레임워크는 이렇다.
스프링 MVC는 이렇다.
디스패처 서블릿이 스프링 MVC의 핵심이다.
DispatherServlet 서블릿 등록
- DispatcherServlet도 부모 클래스에서 HttpServlet을 상속 받아서 사용하고 서블릿으로 동작한다.
- DispatcherServlet -> FrameworkServlet -> HttpServletBean -> HttpServlet - 스프링 부트는 DispatcherServlet`서블릿으로 자동으로 등록하면서 모든 경로 /에 대해서 매핑한다.
요청 흐름
- 서블릿이 호툴되면 Service()가 호출된다.
- 스프링 MVC는 DispatherServlet의 부모인 FrameworkServlet에서 service()를 오버라이드 해두었다.
- FrameworkServlet.service()를 시작으로 여러 메서드가 호출되면서 DispatcherServlet.doDispatch() 가 호출된다.
동작 순서
- 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
- 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
- 핸들러 어댑터 실행: 핸들러 어댑터를 실행한다.
- 핸들러 실행: 핸들러 어댑터가 실제 핸들러를 실행한다.
- modelandview반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 modelandview로 변환해서 반환한다.
- viewResolver 호출: 뷰 리졸버를 찾고 실행한다. (JSP의 경우: InternalResourceViewResolver가 자동 등록)
- view 반환: 뷰 리졸버는 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담당하는 뷰객체를 반환한다.
- 뷰 렌더링: 뷰를 통해서 뷰를 렌더링 한다.
각 자세히 살펴보자
DispatherServlet
- 제일 앞단에서 HTTP Request를 처리하는 Controller
- Spring MVC에서는 HTTP Request가 왔을 때 DispatcherServlet이라 불리는 서블릿이 HTTP Request를 처리한 Controller를 지정한다.
- DispatcherServlet은 일종의 HTTP Request를 처리할 Controller를 지정하는 Controller로 Super Contoller의 역할
HandlerAdapter
- DispatcherServlet이 지정한 Controller를 실행하는 역할
- 다양한 형태의 핸들러(컨트롤러)가 있기 때문에 DispatcherServlet은 어떤 핸들러를 실행해야 하는지 알 수 없다.
- @ controller ,...
Controller(Hanlder)
- HTTP Request를 처리해 Model을 만들고 View를 지정
- DispatcherServlet에 의해 배정된 Controller는 Http Request를 처리하고, Requestd의 메시지를 처리해 필요한 데이터를 뽑아 Model에 저장
- HTTP Request에 따라서 HTTP가 보여줄 View Name을 지정
ModelAndView
- Controller에 의해 반환된 Model과 View가 Wrapping된 객체
- Model: Map<String, Value> 형태의 데이터 저장소
- Model은 Map 자료 구조로, HTTP Request 속의 데이터를 파싱해 Key-Value 형태로 만들어 저장한다.
- View, View Name: 뷰리졸버에서 그릴 뷰를 지정, 뷰 객체를 직접 지정하는게 아니라 View Name을 지정하면, 뷰 리졸버가 뷰를 찾아서 지정해준다.
// 개별 조회 창 띄우기
public ModelAndView programEvaluation(Map<?, ?> rqstMap) throws Exception {
ModelAndView mv = new ModelAndView();
HashMap param = new HashMap<>();
String ad_PK = MapUtils.getString(rqstMap, "ad_PK");
param.put("ad_PK", ad_PK);
List<Map> evaList = null;
if (Validate.isNotEmpty(ad_PK)) {
evaList = PGEV0100Mapper.findEvaList(param);
}
mv.addObject("member", MapUtils.getObject(rqstMap, "member"));
mv.addObject("evaList", evaList);
mv.setViewName("/admin/ev/BD_UIEVA0101");
return mv;
}
ViewResolver
- ModelAndView를 처리하여 View를 그리기
- 모델에 저장된 데이터를 사용해 View를 그린다.
- View는 사용자에게 보여줄 완성된 View이며, 그대로 유저에게 반환된다.
- 특정한 url로 들어갔을 때 우리에게 보여지는 View가 이곳에서 만들어지는 View이다.
장점
1. 컴포넌트의 명확한 역할 분리로 인해 서로간의 결합도를 낮출 수 있다.
- Model은 데이터 및 비즈니스 로직 담당
- View는 사용자 인터페이스 담당
- Controller는 사용자 요청을 받아 Model과 View의 흐름 제어
2. 코드의 재사용성 및 확장성을 높일 수 있다.
- 개발한 Model과 Controller는 여러 View에서 재사용할 수 있고, View도 다른 Model과 함께 재사용할 수 있다.
3. 서비스를 유지보수하고 테스트를 하는데 용이해진다.
- 변경이 필요한 부분을 보다 쉽게 식별할 수 있다.
- 수정이나 확장할 경우 해당 부분만 집중해서 개발할 수 있어서 다른 부분에 영향을 덜 준다.
한계점
1. Model과 View의 의존성을 완전히 분리시킬 수 없다.
- 일반적으로 View는 Contoller와 연결되어 화면을 구성하게 된다. Controller는 여러 개의 View를 가질 수 있게 된다.
- 여기서 Model은 Contoller를 통해 View와 연결된다. Contoller에 의해 하나의 View에 연결되는 Model도 여러개가 될 수 있다.
2. Controller의 역할이 과도하게 커진다면 Massive-View-Controller현상이 나오게 된다.
- 컨트롤러의 부하가 너무 커지는 현상
'개발 노트 > Java' 카테고리의 다른 글
[Java] 자바에서 대입은 항상 변수에 들어 있는 값을 복사한다. (0) | 2024.07.24 |
---|