백엔드 자바 웹 프로그래밍

3.1. MVC 패턴

들어가면서

이번 장에서는 MVC 패턴에 대해 살펴본다. 효과적인 웹 애플리케이션 설계 및 프레임워크 활용을 위해서도 꼭 필요한 개념 이다.

MVC 패턴 학습을 통해

등에 대해 배우고 개발에 활용할 수 있다.



디자인 패턴(Design Patterns)

디자인 패턴은 처음 건축학적 관점에서 출발한 개념 이었으나 1994년 GoF(Gang of Four)의 Design Patterns: Elements of Reusable Object-Oriented Software을 통해 소프트웨어 설계에 공통적으로 발생하는 문제에 대한 재사용 가능한 솔루션으로 제시 되었다.

물론 완벽한 설계란 있을 수 없고 시대의 흐름에 따라 달라진 부분은 있을 수 있지만 시행착오를 통해 스스로 터득해 나가야하는 문제들에 대해 누군가 정리해둔 솔루션이 있다면 당연히 검토할 가치가 있을것이다.

GoF의 디자인 패턴은 생성, 구조, 행동, 동시실행 등의 문제에 대해 여러 패턴들을 제시하고 있으며 UML 클래스 다이어그램을 이용해 구조를 표현하고 있다.

다음은 객체 생성에 대한 문제 해결을 위한 Abstract Factory Pattern 의 예이다.

[그림: Abstract Factory Pattern], 출처-GoF Design Patterns

객체지향프로그래밍은 클래스로 부터 여러 객체를 생성하고 이들을 활용하는 구조로 프로그램에서 객체를 직접 생성하는 것은 당연한 것이지만 이는 프로그램에 종속성을 만드는 요인이 된다. 예를 들어 데이터베이스 연동 프로그램에서 다음과 같은 코드가 있다고 가정해 보자.

ProductDAO dao = new ProductDAO();
dao.insertDB(p);
...

문제가 없어 보이지만 이 코드는 ProductDAO 라는 클래스에 대한 종속성을 만들게 된다. 예를 들어 현재 시스템은 Oracle 데이터베이스를 사용하고 있고 ProductDAO역시 오라클에 맞게 제작된 클래스로 가정해 보자. 이경우 데이터베이스를 MySQL 이나 다른 데이터베이스로 교체할 경우 ProductDAO 를 MySQL에 맞게 다시 다시 구현해 주어야 한다. 그런데 프로그램이 경우에 따라서는 오라클 혹은 MySQL에서 실행되어야 하는 상황이 발생하면 현재 프로그램 구조를 수정할 수밖에 없을 것이다.

Abstract Factory Pattern 은 이러한 경우 유용하게 사용할 수 있으며 직접적인 객체 생성 대신 Factory 클래스에 객체 생성을 위임하는 구조이다. 아래 코드는 전체 패턴을 구현한 것이 아니라 패턴구조로 설계된 경우 클라이언트에서 팩토리를 사용하는 부분만 예로든 것이다.

ProductDAO dao = DAOFactory.create("oracle");
dao.insertDB(p);
...
최근의 개발은 개발자가 직접 애플리케이션 실행을 위한 모든 환경을 설계하고 개발하는 형태가 아니라 프레임워크, 컨테이너 기반으로 개발하기 때문에 직접적인 패턴 구현에 대한 고민은 줄어 들었지만 소프트웨어 설계에 있어서는 여전히 중요한 개념이다.


MVC 패턴

MVC 패턴은 Model-View-Controller 의 약어로 주로 GUI 기반의 애플리케이션 개발에 사용된 디자인 패턴이다. 지금은 백엔드 기반의 웹 애플리케이션 개발의 기본 모델이 되었으며 모바일 앱 및 프론트엔드 기반 웹 애플리케이션 개발이 늘어나면서 MVP(Model-View-Presenter), MVVM(Model-View-ViewModel)과 같은 패턴들도 널리 사용되고 있습니다.

이들 패턴의 공통적인 목적은 화면과 데이터 처리를 분리해 코드간의 종속성을 줄이고 구성요소간의 역할을 명확하게 함으로써 코드 분리가 쉽고 협업을 용이하게 하는데 있다.

여기서는 MVC 패턴에 대해서만 살펴보고 특히 자바 웹 개발에 일반적으로 적용되는 구조를 중심으로 설명한다.

기본적인 MVC 패턴 구조는 다음과 같이 표현 할 수 있다.

[그림: MVC Pattern]

모델(Model)

모델은 데이터를 처리하는 영역이다. 실제 구현에는 데이터베이스와 연동을 위한 DAO(Data Access Object) 클래스와 데이터 구조를 표현하는 DO(Data Object, Entity 라고도 함)클래스로 구성된다.

모델은 뷰나 컨트롤러에 독립적인 구조로 데이터베이스 처리를 필요로 하는 여러 애플리케이션에서 공유가 가능하며 웹 애플리케이션이 아닌 경우에도 사용할 수 있는 형태 이다.

효과적인 DB연동 구현을 위해 JPA(Java Persistance API)를 사용하는 경우 DAO는 생략 되거나 구현 범위가 축소될 수 있다.

뷰(View)

화면을 담당하는 부분이다. JSP가 여기에 해당되며 EL, JSTL을 사용해 컨트롤러로 부터 전달된 데이터의 출력과 HTML, css등을 통해 화면 디자인을 처리 한다. 기본적으로 모델, 컨트롤러와의 종속성이 없도록 구현해야 한다.

MVC패턴으로 역할이 명확하게 분리되면 뷰 구현기술이 꼭 JSP가 될 필요는 없다.

컨트롤러(Controller)

MVC 패턴의 핵심으로 모든 사용자 요청의 중심에 위치 한다. 사용자 요청은 기본적으로 특정 뷰로 바로 가는 것이 아니라 컨트롤러를 통해야 하며 컨트롤러는 사용자 요청에 따라 모델을 이용해 데이터베이스 연동을 처리하고 뷰에 전달 한다. 뷰 전달을 위해서는 데이터가 들어있는 DO 혹은 List<DO> 형태의 객체를 request에 저장뷰로 포워딩 하는 구조를 가진다.

컨트롤러는 특정 뷰를 지정해야 하기 때문에 뷰와 종속관계가 발생할 수 밖에 없는 구조이다. 따라서 규모가 커질수록 컨트롤러가 복잡해지고 관리가 어렵다는 문제가 있다.

컨트롤러 구현은 JSP, Servlet 모두 가능하며 간단한 기능의 구현에는 JSP가 유리한 부분이 많이 있지만 규모와 향후 스프링프레임워크로의 확장등을 생각한다면 Servlet기반의 구현이 권장된다.

컨트롤러를 구현할때 사용자 요청마다 컨트롤러를 만들수도 있고(예를들어 loginForm.html -> LoginController -> main.jsp) 특정 모듈 단위(예를들어 ShopController, MemberController)로 하나의 컨트롤러 안에서 여러 요청 단위(로그인, 회원가입, 정보수정등)를 구분해 처리하는 것도 가능하다. 또한 프론트컨트롤러를 따로 두어 요청에 따른 컨트롤러를 호출할 수 있도록 구성할수도 있다.


실습-1: MVC 웹 애플리케이션 설계

학생정보를 조회하는 간단한 앱을 MVC 패턴 기반으로 설계한다. 설계된 앱은 이후 서블릿 및 JSP 컨트롤러 구현과 연계되어 동작 한다.

실습 코드랩