[디자인패턴] MVC패턴에 대하여

백엔드 개발자 ✨·2022년 7월 16일
0

📌 디자인 패턴이란 ?

디자인 패턴은 건축학적 관점에서 출발한 개념이었으나 1994년 GoF를 통해 소프트웨어 설계에서 공통적으로 발생하는 문제에 대한 재사용 가능한 솔루션으로 제시되었다. 물론 완벽한 설계란 없으며 시대의 흐름에 따라 달라질 수 있지만, 시행착오를 통해 스스로 터득해야 할 문제를 정리해둔 솔루션이 있다면 당연히 검토할 가치가 있는 것이다.

GoF의 디자인 패턴은 생성, 구조, 행동, 동시실행 등의 문제에 대해 여러 패턴을 제시하고 있으며 UML 클래스 다이어그램을 이용해 구조를 표현하고 있다. UML이란 Unified Modeling Language의 약어로 객체지향 설계와 구현을 지원하기 위해 만들어진 일종의 모델링 언어다. 프로그램이 언어와 같은 형태는 아니고 시스템 분석, 설계에 필요한 내용을 여러 다이어그램 형태로 정의한 규격이다.

📌 추상 팩토리 패턴이란 ?

Factory는 '공장'이라는 의미로 디자인 패턴에서 객체를 생성하는 역할을 의미한다. '추상적'이라는 의미를 가진 Abstract는 자바의 추상 클래스에도 사용되는 표현으로 구체적인 내용의 구현을 하위 객체에 임하는 모델이다. 따라서 추상 팩토리는 객체를 생성하는 것을 별도로 구현하되 관련된 구체적인 구현을 하위 클래스에서 담당하게 하는 설계 모델로 이해할 수 있다.

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

ProductDAO dao = new ProductDAO();
dao.insertDB(p);
  • ProductDAO 클래스는 데이터베이스 연동을 구현한 클래스다.
  • insertDB() 메서드는 인자로 상품 객체를 전달받아 DB에 저장한다.

위 코드는 별다른 문제가 없어 보이지만 ProductDAO라는 클래스에 대한 종속성을 만들게 된다. 예를 들어 현재 시스템에서 오라클 데이터베이스를 사용하고, ProductDAO 역시 오라클에 맞게 제작된 클래스라 가정하자. 이 경우 데이터베이스를 MySQL 또는 다른 데이터베이스로 교체할 경우 ProductDAO를 다시 구현해야 한다. 그런데 프로그램이 상황에 맞게 오라클 혹은 MySQL에서 실행되어야 한다면 현재 프로그램의 전반적인 구조를 수정할 수밖에 없을 것이다. 추상 팩토리 패턴은 이러한 경우 유용하게 사용할 수 있다. 직접적인 객체 생성대신 팩토리 클래스에 객체 생성을 위임하는 구조이기 때문이다.

다음 코드는 패턴 구조를 적용한 클라이언트에서 팩토리를 사용하는 부분만 예로 든 것이다.

ProductDAO dao = DAOFactory.create("oracle");
dao.insertDB(p);
  • ProductDAO : 추상 클래스 또는 인터페이스다. ProductDAO 추상 클래스를 상속받는 OracleDAO, MySQLDAO 등의 클래스가 존재한다.
  • DAOFactory : 오라클이나 MySQL용으로 구현된 ProductDAO 타입의 객체를 생성해서 리턴한다.

위의 예시와 같이 create()의 인자로 특정 인스턴스를 요청할 수도 있고 .xml 설정 파일 등을 이용해 코드 수정 없이 확장 가능한 구조도 가능하다.

📌 MVC 패턴이란 ?

모델-뷰-컨트롤러(model–view–controller, MVC)는 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴이다. 이 패턴을 성공적으로 사용하면, 사용자 인터페이스로부터 비즈니스 로직을 분리하여 애플리케이션의 시각적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이 쉽게 고칠 수 있는 애플리케이션을 만들 수 있다. MVC에서 모델은 애플리케이션의 정보(데이터)를 나타내며, 뷰는 텍스트, 체크박스 항목 등과 같은 사용자 인터페이스 요소를 나타내고, 컨트롤러는 데이터와 비즈니스 로직 사이의 상호동작을 관리한다.

1. 모델

모델은 데이터를 처리하는 영역이다. 일반적으로 데이터베이스와 연동을 위한 DAO 클래스와 데이터 구조를 푷ㄴ하는 DO, 엔티티 클래스 등으로 구성된다.
모델은 뷰나 컨트롤러에 독립적인 구조로 데이터베이스 처리를 필요로 하는 여러 애플리케이션에서 공유할 수 있으며 웹 애플리케이션이 아닌 경우에도 사용할 수 있는 형태다.

2. 뷰

뷰는 화면 구성을 담당하는 영역이다. 뷰에서 데이터를 직접 가져오는 방식은 권장하지 않고 주어진 데이터를 출력하는 용도로만 사용하는 것이 바람직하다. 뷰 영역의 구현을 위해 뷰 템플릿 엔진이 사용되며 JSP 역시 이러한 뷰 템플릿 엔진 중 하나이다. HTML 이외에 EL, JSTL 등을 사용해 컨트롤러로부터 전달받은 데이터를 출력하고 HTML, CSS 등을 통해 화면을 디자인한다. 뷰는 기본적으로 모델, 컨트롤러와의 종속성이 없도록 구현해야 한다.

3. 컨트롤러

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

컨트롤러는 특정 뷰를 지정해야 하기 때문에 뷰와 종속관계가 발생할 수밖에 없다. 따라서 프로젝트의 규모가 클수록 컨트롤러는 복잡해지고 관리가 어려워지는 문제가 있다.

컨트롤러의 구현은 JSP, 서블릿 모두 가능하며, 간단한 기능을 구현할 때는 JSP가 유리하지만 규모 확장과 향후 스프링 프레임워크로의 확장 등을 고려한다면 서블릿 기반의 구현을 권장한다.

컨트롤러를 구성하는 세 가지 방법이 있다.

첫 번째는 사용자 요청마다 컨트롤러를 만드는 것이다. 예를 들어 로그인 기능을 구현하려면 'loginForm.html'로 데이터를 입력받고 LoginController에서 처리하고 결과를 보여주는 'main.jsp'가 필요한데, 각각의 기능 구현을 동일한 방식으로 처리하게 되면 기능(회원가입, 정보 수정 등)마다 컨트롤러를 만들어야 한다.
두 번째로 특정 모듈 단위로 하나의 컨트롤러 안에서 여러 요청 단위를 구분해 처리할 수 있다. 예를 들어 MemberController 안에서 로그인, 회원가입, 정보 수정 등을 처리할 수 있따.
마지막으로 프론트 컨트롤러를 따로 두어 모든 요청을 하나의 컨트롤러로 모은 다음 요청에 따라 구현 컨트롤러를 호출하도록 구성할 수 있다.

profile
개발공부 기록용

0개의 댓글