티스토리 뷰

 

MVC 패턴 - 개요

각자 자기가 맡은 일만 하자!

하나의 서블릿이나 JSP만으로 비즈니스 로직과 뷰 렌더링까지 모두 처리하게 되면, 너무 많은 역할을 하게되고 결과적으로 유지보수하기 어려워진다. 비즈니스 로직을 호출하는 부분에 변경이 발생해도 해당 코드를 손대야 하고, UI를 변경할 일이 있어도 비즈니스 로직이 함께 있는 해당 파일을 수정해야한다.

 

즉, 하나의 파일 안에 비즈니스 로직 코드와 UI를 담당하는 코드가 함께 있다는 것이다. HTML 코드 하나 수정하는데 수백줄의 비즈니스 로직 코드가 함께 있는 것은 매우 비효율적이고, 이와 반대의 경우에도  정말 비효율적이다.

이를 현실에서 비유해보면 경찰서에서 소방업무까지 담당하고 있다면..? 생각만 해도 혼란스럽다

 

JSP같은 뷰 템플릿은 화면을 렌더링 하는데 최적화되어있고, 서블릿은 자바 코드를 실행하는데 최적화되어있다

-> 본인들의 맡은 일만 담당하는 것이 좋다. 마치 회사에서 담당 부서가 나뉜 것 처럼..

 

 

MVC(Model, View, Controller)

MVC 패턴은 앞에서 다룬 서블릿이나 JSP로 처리하던 것을 컨트롤러라는 영역으로 서로 나눈 것을 말한다. 웹 어플리케이션은 보통 이러한 MVC 패턴을 사용한다.

 

  • 모델(M): 뷰에 출력할 데이터를 담아두는 역할. 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주기 때문에, 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되고 화면을 렌더링하는 일에 집중할 수 있다.
  • 뷰(V): 모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다. HTML을 생성하는 것과 같은 일
  • 컨트롤러(C): HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다. 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.

 

참고
컨트롤러에 비즈니스 로직을 둘 수도 있지만, 이렇게 되면 컨트롤러가 너무 많은 역할을 담당한다. 그래서 일반적으로 비즈니스 로직은 서비스(Service)라는 계층을 별도로 만들어서 처리한다. 그리고 컨트롤러는 비즈니스 로직이 있는 서비스를 호출하는 역할을 담당한다. 참고로 비즈니스 로직을 변경하면 비즈니스 로직을 호출하는 코드도 변경될 수 있다.

이전 포스팅에서 설명한 서블릿, JSP 방식을 MVC 패턴을 적용한 코드를 살펴보자.

@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {

    MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));

        Member member = new Member(username, age);
        memberRepository.save(member);

        // Model에 데이터를 보관한다.
        request.setAttribute("member", member);

        String viewPath = "/WEB-INF/views/save-result.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }


}

회원을 저장하는 기능을 담당하는 회원 저장 컨트롤러이다.

HttpServletRequest를 Model로 사용하고 request가 제공하는 setAttribute 함수를 사용하면 request 객체에 데이터를 보관해서 View에 전달할 수 있다. View에서는 request.getAttribute 함수를 이용해서 데이터를 꺼낼 수 있다.

 

회원 저장 - 뷰

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
성공
<ul>
    <li>id = ${member.id}</li>
    <li>username = ${member.username}</li>
    <li>age = ${member.age}</li>
</ul>
<a href="/index.html">메인</a>
</body>
</html>

이전 포스팅에서 설명한 멤버 저장 코드는 비즈니스 로직과 UI 코드가 함께 있어 비즈니스 로직을 수정하든 UI를 수정하든 동일한 파일에 접근해서 코드를 수정해야했는데, MVC 패턴을 적용한 코드를 보면 컨트롤러 로직과 뷰 로직을 확실하게 분리한 것을 확인할 수 있다. 향후 뷰에 수정이 발생하면 뷰 로직만 변경하면 된다 !

댓글