* MVC 패턴
- 디자인 패턴이란?
디자인 패턴(Desing Pattetn)
- 처음에는 건축학적 관점에서 출발한 개념이었음
- 1994년 GoF의 ≪Design Patterns: Elements of Reusable Object-Oriented Software≫를 통해 소프트웨어 설계에서 공통적으로 발생하는 문제에 대한 재사용 가능한 솔루션으로 제시됨
- GoF의 디자인 패턴은 생성, 구조, 행동, 동시실행 등의 문제에 대해 여러 패턴을 제시하고 있으며 UML 클래스 다이어그램을 이용해 구조를 표현하고 있음
UML(Unified Modeling Language)
- 객체지향 설계와 구현을 지원하기 위해 만들어진 일종의 모델링 언어
- 시스템 분석, 설계에 필요한 내용을 여러 다이어그램 형태로 정의한 규격임
- 추상 팩토리 패턴이란?
추상 팩토리(Abstract Factory) 패턴
- 추상(Abstract): 자바의 추상 클래스 Abstract Class에도 사용되는 표현으로 구체적인 내용의 구현을 하위 객체에 위임하는 모델임
- 팩토리(Factory): 디자인 패턴에서 객체를 생성하는 역할을 의미함
- 따라서 추상 팩토리는 객체를 생성하는 것을 별도로 구현하되 관련된 구체적인 구현을 하위 클래스에서 담당하게 하는 설계 모델로 이해할 수 있음
추상 팩토리(Abstract Factory)의 UML 클래스 다이어그램
- 객체 생성에 대한 문제 해결을 위한 디자인 패턴
- MVC 패턴이란?
MVC 패턴
- Model-View-Controller
- GUI(Graphical User Interface) 기반의 애플리케이션 개발에 사용되는 디자인 패턴
- 지금은 백엔드 기반의 웹 애플리케이션 개발의 기본 모델이 되었음
- 모바일 앱 및 프런트엔드 기반 웹 애플리케이션 개발이 늘어나면서 MVP(Model-ViewPresenter), MVVM(Model-View-ViewModel) 과 같은 패턴도 널리 사용되고 있음
- 목적 : 화면과 데이터 처리를 분리하여 코드 간 종속성을 줄이는 것
- 구성요소 간 역할을 명확하게 하여 코드를 쉽게 분리하고 협업이 용이해짐
- 사용자가 컨트롤러를 조작하면 모델에서 데이터를 가져와 이를 바탕으로 뷰에 정보가 띄워지는 방식
MVC 패턴 구조
모델(Model)
- 데이터를 처리하는 영역
- 구성
- DAO(Data Access Object) - 일반적으로 데이터베이스와 연동을 위한 클래스
- DO(Data Object, 엔티티 클래스) - 데이터 구조를 표현
- 모델은 뷰나 컨트롤러에 독립적인 구조로 데이터베이스 처리를 필요로 하는 여러 애플리케이션에서 공유할 수 있으며, 웹 애플리케이션이 아닌 경우에도 사용할 수 있음
- 모델1 구조
- 웹 브라우저의 요청을 JSP가 직접 처리
- 웹 브라우저의 요청을 받은 JSP는 자바빈이나 서비스 클래스를 사용해서 웹 브라우저가 요청한 작업을 처리하고 그 결과를 클라이언트에 출력
- 모델2 구조
- 웹 브라우저의 요청을 하나의 서블릿이 받음
- 서블릿은 웹 브라우저의 요청을 알맞게 처리한 후 그 결과를 보여줄 JSP 페이지로 포워딩
- 포워딩을 통해 요청 흐름을 받은 JSP 페이지는 결과 화면을 클라이언트에 전송
뷰(View)
- 화면 구성을 담당하는 영역
- 주어진 데이터를 출력하는 용도로만 사용하는 것이 바람직 ( 뷰에서 데이터를 직접 가져오는 방식은 권장하지 않음 )
- 뷰 영역의 구현을 위해 뷰 템플릿 엔진이 사용되며 JSP 역시 이러한 뷰 템플릿 엔진 중 하나
- HTML 이외에 EL, JSTL 등을 사용해 컨트롤러로부터 전달받은 데이터를 출력하고 HTML, CSS 등을 통해 화면을 디자인
- 뷰는 기본적으로 모델, 컨트롤러와의 종속성이 없도록 구현해야 함
컨트롤러(Controller)
- MVC 패턴의 핵심으로 모든 사용자 요청의 중심에 위치
- 사용자 요청은 특정 뷰에 바로 전달되지 않고 컨트롤러를 통해야 함
- 사용자 요청에 따라 모델을 통해 데이터베이스와 연동하여 데이터를 처리하고 뷰에 전달
- 뷰로 전달하기 위해 데이터가 들어 있는 DO 혹은 List 형태의 객체를 request 에 저장한 후 포워딩함
- 컨트롤러는 특정 뷰를 지정해야 하기 때문에 뷰와 종속관계가 발생할 수밖에 없음
- 프로젝트의 규모가 클수록 컨트롤러는 복잡해지고 관리가 어려워지는 문제가 있음
컨트롤러의 구현
- JSP, 서블릿 모두 가능
- JSP: 간단한 기능을 구현할 때 유리
- 서블릿: 규모 확장과 향후 스프링 프레임워크로의 확장 등에 유리( 컨트롤러를 호출하기 )
컨트롤러를 구성하는 세 가지 방법
- 사용자 요청마다(URL 패턴 마다) 컨트롤러를 만들기
- 특정 모듈 단위로 하나의 컨트롤러 안에서 여러 요청 단위를 구분해 처리하기
- 프런트 컨트롤러를 따로 두어 모든 요청을 하나의 컨트롤러로 모은 다음 요청에 따라 구현 컨트롤러를 호출하기
*서블릿 컨트롤러 설계
- 클라이언트 요청 처리
컨트롤러의 가장 기본적인 기능 세 가지
- 클라이언트 요청 처리
- 클라이언트 요청을 단일 컨트롤러에서 처리할 것인지 / 개별 컨트롤러에서 처리할 것 인지 결정해야 함
- 서블릿은 URL 요청을 GET, POST 등의 HTTP 메서드를 통해 처리하는 구조이기 때문 에 여러 URL 패턴을 하나의 서블릿에서 처리할 수 있지만 URL에 따라 다른 처리를 구현할 수는 없음
- 입력 값 핸들링
- 뷰 이동
예시
1) 쇼핑몰 제품 등록 / 삭제 기능
- 두 URL 요청을 하나의 서블릿으로 처리하도록 URL 매핑 설정을 할 수 있으나, 두 요청 모두 GET 방식이라면 URL이 다르더라도 동일한 doGet( ) 메서드가 호출되기 때문에 어떤 요청이 호출된 것인지 구분할 수 없음
- 따라서 각각의 URL 요청을 별도의 서블릿으로 구현해야 함
2) 회원 관리 프로그램 회원 가입 / 승인 / 수정 / 탈퇴(삭제) / 로그인 기능
- 각각의 요청을 처리하기 위한 컨트롤러가 있어야 함
- 입력/요청 화면과 입력 데이터를 받아 이를 처리하는 컨트롤러, 처리된 결과를 보여주기 위한 화면이 필요
- 이 경우 각각의 컨트롤러를 구현해야 하지만 같은 단위의 업무를 하나의 컨트롤러에서 처리하는 것이 구조적으로 관리가 쉬울 수 있음
- 물론 하나의 컨트롤러에서 처리할 요청이 지나치게 많은 경우 오히려 코드 관리가 어려 울 수 있으므로 주의
사용자의 요청을 구분해 하나의 서블릿에서 처리하기 위한 두 가지 방법
1. URL의 파라미터 이용
- URL에 action과 같이 별도의 파라미터를 두어 요청을 구분
- member : 서블릿 URL 매핑값
- action : 요청을 구분하기 위한 파라미터
- 요청에는 회원 정보, 로그인 아이디 등의 사용자 데이터가 추가로 포함
- GET, POST 방식이 모두 가능
- 컨트롤러에서는 action 값을 비교하여 별도의 메서드 구현 등의 방식으로 처리
- 비교적 간단한 방법이지만 action 파라미터의 구조가 변경되며 관련된 HTML, JSP, 컨트롤러의 수정이 필요하다는 단점이 있음
- 실제 구현 예시 - 분기문 사용
2. 프런트 컨트롤러 구현
- 모든 요청의 진입점이 되는 컨트롤러가 있고 여기서 서브 컨트롤러를 호출하는 구조
- 좀 더 복잡한 구조를 체계적으로 처리할 수 있음
- 프런트 컨트롤러 패턴으로 정립되어 있어 여러 구현에 응용되는 디자인 패턴
- 모든 요청을 하나로 모으는 방법이 필요하며, 일반적으로는 서블릿 매핑의 구조적인 특징을 활용
- /member: 회원 관리 웹 애플리케이션 콘텍스트 혹은 서비스 구분 경로
- *.do: 서블릿 URL 매핑값으로 모든 요청은 하나의 서블릿을 호출함
- 컨트롤러에서는 .do 앞의 요청 이름(create, login)으로 구분하여 별도의 메서드 혹은 서브클래스를 통해 실행함
- 장단점
- 장점
- 요청에 대한 파라미터 없이 명확한 이름(전 예시의 create, login)으로 요청할 수 있음
- 요청에 대한 URL 관리가 필요 없음
- 단점
- 전체 시스템(네이버)이 세부 시스템(회원관리, 블로그, 카페)으로 분리되어 있는 경우 : 콘텍스트를 분리하는 것은 세션 관리 등에 부담이 갈 수 있음 - 예) 네이버와 같은 포털 형태
- 단일 콘텍스트에 경로로 구분하는 경우: 프런트 컨트롤러에서 모든 요청을 조건문과 메서드 구현만으로 처리하기에는 컨트롤러 클래스가 비대해짐 → 규모가 어느 수준 이상이 되면 경로에 따라 서브 컨트롤러로 포워딩하는 처리가 필요함
- 장점
서브 컨트롤러 구현
- URL 요청을 분석해 사용자 요청을 구분하는 작업이 우선적으로 필요
- 메서드를 이용해 사용자 요청을 분리해서 처리
- switch(혹은 if ) 문을 사용하는 구조는 기능 추가 또는 변경이 필요할 때 조건문도 함께 관리해야 하는 문제가 있음
- Command 패턴을 사용하면 switch(혹은 if) 구조 없이 해당 요청에 맞는 특정 컨트롤러가 실행되도록 구현할 수 있음
서브 컨트롤러를 운영하는 프런트 컨트롤러 설계
- 먼저 서브 컨트롤러의 규격을 정의한 인터페이스가 필요
- 다음으로 필요한 서브 컨트롤러를 구현
- 앞의 다중 요청 처리 서블릿을 서브 컨트롤러 규격에 맞게 수정함
- 기본적으로는 단일 기능을 수행
- 서브 URL 경로를 추가로 구분해 메서드 단위로 여러 요청을 처리하도록 구현하는 것도 가능
- 입력값 핸들링
- 서블릿에서 클라이언트의 입력값을 처리하려면 request.getParameter( )를 이용
- 파라미터가 한두 개라면 문제없겠지만 회원 가입과 같이 여러 정보가 전달되는 경우 모든 값을 request.getParameter( )로 받는 것은 문제
- DAO 클래스와 연동을 위해서는 입력값을 Member 객체로 만든 후에 전달해야 함
- JSP에서는 useBean 액션을 통해 입력값을 Member 객체로 쉽게 만들 수 있었음 (
- 서블릿에서는 제공 X - 별도의 라이브러리를 사용해야 함
- 대표적으로 Apache Commons BeanUtils가 쓰임
- 뷰 이동
뷰 이동
- 컨트롤러에서 사용자 요청을 처리한 다음에는 적절한 뷰로 이동할 수 있어야 함
- 뷰에서 보여줄 데이터를 포함해서 이동해야 하는 경우와 그렇지 않은 경우로 나뉨
데이터 포함 X 경우
- 해당 페이지로 리디렉션 Redirection할 수 있음
- JSP, 서블릿 모두 response.sendRedirect( )를 사용
데이터 포함 O 경우
- request scope object에 속성으로 데이터를 넣은 후 원하는 페이지로 포워딩
- 데이터 활용 목적에 따라 session 또는 application을 사용
- 여러 데이 터를 포함하는 것도 가능
'개발 공부 > Java' 카테고리의 다른 글
[JSP/스프링] - 리스너와 필터 (0) | 2024.01.12 |
---|---|
[JSP/스프링] - 데이터베이스와 JDBC (0) | 2024.01.10 |
[JSP/스프링] - JSP 응용 (0) | 2024.01.08 |
[JSP/스프링] - JSP의 기초 (0) | 2024.01.05 |
[JSP/스프링] - 서블릿의 이해 (0) | 2024.01.04 |