하나의 서블릿이나 JSP만으로 비즈니스 로직과 뷰 렌더링까지 모두 처리하게 되면, 너무 많은 역할을 하게되고, 결과적으로 유지보수가 어려워진다.
비즈니스 로직을 호출하는 부분에 변경이 발생해도 해당 코드를 수정해야하고, UI를 변경할 일이 있어도 비즈니스 로직이 함께 있는 파일을 수정해야한다. 코드의 양이 수백 수천줄이라면 이 작업은 매우 어려워지고 복잡해진다.
변경의 라이프 사이클
둘 사이의 변경 라이프 사이클이 다르다는 점이다. UI를 일부 수정하는 일과 비즈니스 로직을 수정하는 일은 각각 다르게 발생할 가능성이 매우 높고 대부분 서로에게 영향을 주지 않는다.
이렇게 변경의 Life Cycle이 다른 부분을 하나의 코드로 관리하는 것은 유지보수하기에 좋지 않다.
기능 특화
JSP 같은 뷰 템플릿은 화면을 렌더링 하는데 최적화 되어있기 때문에 이 부분만 담당하는 것이 훨씬 효과적이다.
MVC
Model
- 뷰에 출력할 테이터를 담아둔다.(DB) 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주기 때문에 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되고, 화면을 렌더링 하는 작업에만 집중할 수 있다.
View
- 모델에 담겨있는 데이터를 사용하여 화면을 그린다.(HTML 생성)
Controller
- HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다. 그리고 뷰에 전달할 결과 데이터를 조회하여 모델에 담아준다.
컨트롤러에 비즈니스 로직을 둘 수도 있지만, 이렇게 되면 컨트롤러가 너무 많은 역할을 담당한다.
일반적으로 비즈니스 로직은 서비스(Service)라는 계층을 별도로 만들어서 처리한다. 그리고 컨트롤러는 비즈니스 로직이 있는 서비스를 호출하는 기능을 담당한다.
서블릿을 컨트롤러, JSP를 뷰로 하여 MVC패턴을 적용시켜보자
모델은 HttpServletRequest 객체 내부의 데이터 저장소를 사용
- dispatcher.forward() : 다른 서블릿이나 JSP로 이동할 수 있는 기능, 서버 내부에서 다시 호출 발생
- /WEB-INF ==> 이 경로 내부에 JSP가 있으면 외부에서 직접 JSP를 호출할 수 없다.
- 컨트롤러를 통해서 JSP호출
- 위와 같이 직접 호출할 수가 없음
redirect는 실제 클라이언트에 응답이 나갔다가, 클라이언트가 redirect경로로 다시 요청한다. 따라서 클라이언트가 인지할 수 있고, URL 경로도 실제로 변경된다. 하지만 forward는 서버 내부에서 호출이 일어나기 때문에 클라이언트가 인지하지 못한다.
- 상대 경로 사용했음
- /servlet-mvc/members/save로 간다.
회원 저장
- setAttribute를 통해 request에 저장하고 getAttribute를 통해 꺼낸 뒤 Member로 캐스팅하여 값을 꺼냄
- 하지만 이렇게 데이터를 처리하는 과정은 복잡
- jsp에서 제공하는 표현식을 사용하면 좀 더 간단하게 처리가능
- property 접근법으로 위와 같이 간단하게 처리할 수 있다.
기능과 역할을 분리를 했음
회원 목록 조회
- jsp가 제공하는 jstl이라는 특별한 태그들을 사용하여 코드를 작성하면 더 깔끔하게 작성할 수 있음
- items는 request에 넣은 key값으로 조회하여 가져오고 그 리스트들 중에서 forEach를 통해 하나씩 꺼내는 것이다
- for문과 구조 동일
MVC 패턴의 한계
뷰는 화면을 그리는 역할에 충실한 덕분에, 코드가 깔끔하고 직관적.
컨트롤러는 현재 중복이 많고, 불필요한 코드들도 보임
MVC 컨트롤러의 단점
- forward 중복
- View로 이동하는 코드가 항상 중복 호출되어야 한다. 이 부분을 메서드로 추출하더라도 해당 메서드가 항상 직접 호출되어야한다.
- ViewPath 중복
- prefix : /WEB-INF/views/
- suffix : .jsp
- 만약 jsp가 아닌 thymeleaf 같은 다른 뷰로 변경한다면 전체 코드를 다 변경해야함
- 사용하지 않는 코드
- 현재 response는 현재 코드에서 사용되지 않는다.
- HttpServletRequest, HttpServletResponse를 사용하는 코드는 tc를 작성하기도 어렵다
- 공통 처리가 어렵다.
- 기능이 복잡해질 수록 컨트롤러에서 공통으로 처리해야 하는 부분이 점점 더 증가할 것이다. 공통 기능을 메서드로 추출하더라도 해당 메서드를 항상 호출해야함
이를 해결하기 위해선 컨트롤러 호출 전에 먼저 공통 기능을 처리해야한다.
프론트 컨트롤러(Front Controller) 패턴을 도입하면 이를 깔끔하게 해결할 수 있다.
스프링 MVC의 핵심도 바로 Front Controller이다!
반응형
'Spring > Spring MVC' 카테고리의 다른 글
View 분리 (0) | 2021.04.14 |
---|---|
프론트 컨트롤러 패턴 (0) | 2021.04.13 |
JSP로 회원 관리 웹 애플리케이션 만들기 (0) | 2021.04.09 |
서블릿으로 회원 관리 웹 애플리케이션 만들기 (0) | 2021.04.06 |
HTTP 응답 데이터 (0) | 2021.04.06 |