MVC (Model - View - Controller) 등장배경
유지보수의 어려움 (너무 많은 역할)
- 서블릿으로 개발 => 뷰(View)화면을 작업할 때 자바 코드가 섞여 지저분하고 복잡하다. (유지보수가 어려움.)
- 위 문제를 개선하고자 jsp로 개발 => 뷰를 생성하는 html 코드와 비지니스 로직을 처리하는 자바 코드가 분리 가능해졌다.
- 하지만, jsp 안에 자바로 처리하는 부분, 데이터 처리 부분, 화면을 보여주는 html 코드 등 다양한 모든 작업들이 jsp파일 안에서 모두 처리된다. (즉, jsp가 너무 많은 역할을 수행하고 있음..! => 유지보수가 어려움.)
- 따라서, 위 같은 문제를 해결하고자 MVC 패턴이 등장하게 되었다.
변경의 라이프 사이클
변경 주기가 다른 부분은 분리해야 한다.
- 화면을 처리하는 뷰와 비지니스 로직을 수정하는 일은 각각 다르게 발생할 가능성이 높다.
- 또한, 이 둘은 서로에게 영향을 주지 않는다. => 분리가 가능하다.
- 즉, 변경의 라이프 사이클이 다른 부분을 하나의 코드에서 관리하는 것은 유지보수하기 좋지 않다. (물론 UI가 많이 변하면 함께 변경될 가능성도 있다.)
기능 특화
- jsp와 같은 뷰 템플릿은 화면을 렌더링하는데에만 기능이 특화되어있기 때문에 그 작업에만 집중할 수 있도록 하는 것이 가장 효과적이다.
MVC (Model - View - Controller)
컨트롤러(Controller)
HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다. 그리고 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.
* 컨트롤러에 비즈니스 로직을 둘 수도 있지만, 이렇게 되면 컨트롤러가 너무 많은 역할을 담당한다. 그래서 일반적으로 비즈니스 로직은 서비스(Service)라는 계층을 별도로 만들어서 처리한다. 그리고 컨트롤러는 비즈니스 로직이 있는 서비스를 호출하는 역할을 담당한다.
즉, 컨트롤러 => 비즈니스 로직 호출 / 서비스 => 비즈니스 로직 수행
모델(Model)
뷰에 출력할 데이터를 담아둔다. 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주는 덕분에 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되고, 화면을 렌더링 하는 일에 집중할 수 있다.
- Model은 HttpServletRequest 객체를 사용한다. request는 내부에 데이터 저장소를 가지고 있다.
뷰(View)
모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다. (HTML을 생성하는 부분)
MVC 패턴 발전과정
MV 패턴
- 너무 많은 역할을 담고 있어서 비지니스 로직을 담고 있는 부분도 다 수정해야하고, 뷰를 담당하는 부분도 다 수정해야하는 어려움이 있다.
Model 1 패턴
- 사용자가 요청을 하면 컨트롤러에서 비지니스 로직을 수행한다.
- 수행한 결과물(데이터)을 모델에 담아서 뷰 로직으로 전달해서 뷰를 그린다.
- 만들어진 화면(뷰)을 사용자에게 전달한다.
서로의 의존관계를 분리시킬 수 있다.
Model 2 패턴
MVC 패턴의 한계
컨트롤러의 중복
forward 중복
View로 이동하는 코드가 항상 중복 호출되어야 한다. 물론 이 부분을 메서드로 공통화해도 되지만, 해당 메서드도 항상 직접 호출해야 한다.
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath); dispatcher.forward(request, response);
컨트롤러에서 계속 중복되어서 나타난다.
ViewPath의 중복
뷰의 경로를 설정할 때 중복되는 경로가 발생한다.
String viewPath = "/WEB-INF/views/new-form.jsp";
prefix: /WEB-INF/views/
suffix: .jsp
- 위의 앞, 뒤 부분이 중복된다.
- 또한, 뷰 템플릿을 다른 뷰로 바꾼다면 전체코드를 바꾸어야 하는 문제가 발생한다.
사용하지 않는 코드
- HttpServletRequest , HttpServletResponse 를 사용할 경우도 있고 아닌 경우도 존재한다.
- 또한, HttpServletRequest , HttpServletResponse 를 사용하는 코드는 테스트 케이스를 작성하기도 어렵다.
공통 처리가 어려움
기능이 복잡해질수록 컨트롤러에서 공통으로 처리해야 하는 부분이 점점 더 많이 증가할 것이다. 단순히 공통 기능을 메서드로 뽑으면 될 것 같지만, 결과적으로 해당 메서드를 항상 호출해야 하고, 실수로 호출하지 않으면 문제가 될 것이다. 그리고 호출하는 것 자체도 중복이다.
=> 해결하려면 컨트롤러 호출 전(서블릿 호출 전)에 먼저 공통 기능을 처리해야 한다.
따라서, 이를 해결하기 위해 나온 것이 " 프론트 컨트롤러(Front Controller) 패턴"이다.
스프링MVC의 핵심은 이 프론트 컨트롤러에 있다.
'Spring' 카테고리의 다른 글
스웨거(Swagger)란? (1) | 2024.04.26 |
---|---|
HTTP 요청 및 응답 (0) | 2023.10.10 |
웹 애플리케이션 이해 (0) | 2023.10.06 |
AOP (Aspect Oriented Programming) (0) | 2023.10.03 |
JPA(Java Persistance API) (0) | 2023.09.30 |