개발 협업에 있어 아주 유용한 디자인 패턴에 대해 알아보자.


◆ 디자인 패턴

여태까지의 작업은 유지보수나 개발 효율을 고려하지 않고 작업을 했다.
때문에, 중복되는 처리들도 매번 작성해야 하고 완성된 프로젝트의 DB처리가 바뀌게 된다면 대대적인 보수가 일어나야 한다.

이러한 부분들을 고려해서 나오게 된 것이 디자인 패턴이라는 것이고,
이 중 제일 많이 사용되는 것이 MVC패턴이다. (1979년도에 발표된 개발 기법)
또한 이는 웹(Web)에 국한된 것은 아니다.


◆ MVC(Model, View, Controller)패턴

역할별로 세분화 시킨 모듈(class)들을 만들어서 프로그램이 돌아갈 수 있게 하는 기법

  • Model

    : 데이터의 변경/확보 작업을 역할을 담당

  • View

    : 데이터를 출력하는 역할을 담당

  • Controller

    : 처리에 필요한 Model과 View를 연결시키는 중간 역할을 담당


▶ 작동구조

request → [ Controller ] ⇔ [ Model ]
[ Controller ] ⇔ [ View ] → response

  • 이 MVC패턴을 쉽게 설계할 수 있도록 도와주는 프레임워크 중에 SPRING이 있다.
  • Model과 View는 보통 인터페이스로 만들어두고 구현해서 여러 경우를 대비해서 쓸 수 있도록 설계 한다.


◆ 웹에서의 MVC패턴

▶ Controller

Model에서 필요한 데이터를 일부 만들어주고 보낸 후 Model에서 다시 처리한 결과물을 받아 View로 전달해 주는 역할 ( Servlet으로 작성 )
이때 forwarding이라는 기술을 쓰게 된다.


▶ Model

Controller에서 보내준 일부 객체들을 받아 데이터베이스처리 등등을 담당
즉, 대부분의 스크립트렛( <%~%> )에서 처리했던 일들을 하게 된다. ( class로 작성 )


▶ View

Model에서 처리한 결과물을 Controller로부터 받아서 화면으로 출력해주는 역할( jsp로 작성 )


▶ Controller 작성

1. extends HttpServlet하여 Controller역할을 하는 서블릿을 만든다.

서블릿을 만든 후 service()메서드를 오버라이드하여 작성한다. 이때, 인자는 HttpServletRequest req, HttpServletResponse res 라고 가정


2. forwarding

  • 포워딩
    RequestDispatcher을 이용해 포워딩한다. 이때 포워딩된 페이지에 request객체와 response객체를 인자로 전달하여 공유할 수 있다.
RequestDispatcher rd = req.getRequestDispatcher("/index.jsp"); 
rd.forward(req, res);
//또는  줄로 
req.getRequestDispatcher(/index.jsp).forward(req,res); 

request객체의 getRequestDispatcher(“포워딩경로”)를 통해 RequestDispatcher객체를 뽑아내어 request객체와 response객체를 인자로 넘겨주며 포워딩한다.
=> 주소창의 경로는 바뀌지 않고, 제어권만 넘겨주고 index.jsp(뷰)로 이동하게 된다.


  • View로 데이터 넘겨주기
    View로 데이터를 넘겨주려면 포워딩 하기 전에 데이터를 request객체를 이용하여 세팅해야한다.
// Controller or Model
request.setAttribute(“키”,데이터);

// View(jsp)
request.getAttribute(“키”); //  View에서 받을  있다.

단, request.setAttribute는 일회성 데이터만 저장하기 때문에 forwarding한곳 까지만 데이터가 유지되고 사라진다.
( 즉, RequestDispatcher객체로 포워딩 했을 시 해당 서블릿의 request객체와 포워딩된 페이지의 request객체가 같은 객체이기 때문에 데이터를 공유할 수 있는 것이다. )

response.sendRedirect()의 포워딩의 경우 요청된 request객체와 포워딩 된 페이지의 request객체가 다르기 때문에 데이터를 공유할 수 없다!


※ WEB-INF안의 파일들은 보안상 접근이 안 되지만, forwarding을 이용하면 해당 경로에 있는 파일 또한 접근이 가능해진다. 따라서 보안을 위해 WEB-INF안에 forwading할 파일을 넣어두고 사용할 수도 있다.


 
@WebServlet("/index")
public class IndexController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        System.out.println("index controller execute");
        GreetModel model = new GreetModel();
        String msg = model.createMessage();
        req.setAttribute("msg", msg);
        RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/view/index.jsp");
        rd.forward(req, res);
    }
}


▶ Model

Model은 일반 클래스로 작성하여 데이터를 만들어 내거나 변경하는 용도로 사용한다.

public class GreetModel {
    public String createMessage() {
        return "안뇽하세욜";
    }
}


▶ View

View는 jsp로 작성하고, Controller에서 보낸 데이터는 request.getAttribute()로 받아낸다.

<h2>Web MVC</h2>
<%
System.out.println("IndexView execute");
String msg = (String) request.getAttribute("msg");
out.println(msg);
%>
  • 이렇게 MVC패턴으로 만들어진 웹은 View가 아닌 Controller로 최초 접근한다.
  • request, response로 직접 제어해야 하는 데이터들은 Model에서 제어할 수 없기 때문에 Controller에서 최소한의 처리를 해두고 Model에 보낸다. 그 후 나머지 작업은 Model에서 한다.
    ( 또는 controller에서 request와 response객체를 모델로 넘겨주어 작업 할 수도 있다. )


위 과정의 MVC패턴 구현을 좀 더 간편하게 도와주는 SpringFramework가 있다.
Spring을 이용해 패턴을 구현하게 되면 컨트롤러에서 해야할 작업이 확연히 줄어들게 된다.
SpringFramework공부하기