CS/DesignPattern

(DesignPattern) FrontController - Version02 (View 분리)

주누 2021. 5. 2. 16:48

jwdeveloper.tistory.com/291

 

(DesignPattern) FrontController 패턴이란? (with FrontController - Version01)

이번 포스팅에서는 FrontController 패턴을 소개하고자 한다. Spring의 가장 핵심적인 Servlet인 DispatcherServlet은 FrontController 패턴으로 구성되어있다. FrontController 패턴이 무엇인지에 대해서 이해하..

jwdeveloper.tistory.com

 

Version01 문제점


위의 Version01의 문제점은 무엇일까?
모든 컨트롤러에서 뷰로 이동하는 과정에서 중복된 코드가 발생되었다.


해결방안

이를 위해서 뷰를 처리를 전담하는 객체를 만들어보자!
아래의 그림에서 MyView라는 객체가 추가된 것을 볼 수 있다.

 

MyView의 역할은 위에서 언급한 중복된 코드 (View 랜더링)를 처리하는 작업을 수행한다.

FrontController - Version02

우리는 기존의 컨트롤러에서 뷰 랜더링 하는 부분을 따로 빼려고 한다. 그러기 위해선 아래 두 가지 과정이 필요하다.

  • MyView 생성
  • 인터페이스의 반환 타입 MyView로 변경
  • 기존 컨트롤러의 뷰 랜더링 과정 삭제

코드를 통해서 리펙토링 해보자!

 

컨트롤러 인터페이스 생성

version01에서는 컨트롤러에서 뷰 랜더링 책임을 가졌기 때문에 반환 타입이 없었지만 현재는 반환 타입의 책임 갖는 객체를 생성하기 때문에 컨트롤러의 반환 타입을 MyView로 생성한다.

public interface ControllerVersion02 {

    MyView process(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException;
    
}

 

MyView 생성

위에서 언급하였던 기존의 뷰 랜더링 부분을 담당하는 MyView 클래스를 생성한다. 

public class MyView {

    private final String viewPath;

    public MyView(final String viewPath) {
        this.viewPath = viewPath;
    }

    public void render(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        final RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }
}

Version01 컨트롤러의 중복 코드

폼, 저장, 조회 클래스 생성

Version01과 달리 뷰 랜더링 하는 부분의 책임을 MyView에게 위임하고 컨트롤러는 조회 생성의 책임만을 갖는다.
(동어반복이기에 폼, 저장 컨트롤러는 생략 -> Code Link 참고!)

public class MemberListController implements ControllerVersion02 {

    private final MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    public MyView process(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        final List<Member> members = memberRepository.finalAll();
        request.setAttribute("members", members);

        return new MyView("/WEB-INF/views/members.jsp");

    }
}

Version01 비즈니스 컨트롤러 코드

FrontController 생성

FronController도 version01과 비교해서 많이 변화는 것이 없고 단순히 기존의 컨트롤러에서 담당했던 뷰 랜더링 기능을
MyView에서 담당하기에 render 메서드를 호출한다.

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String requestURI = request.getRequestURI();
    ControllerVersion02 controller = controllerMap.get(requestURI);

    if (controller == null) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    MyView myView = controller.process(request, response);
    myView.render(request, response);
}

 

Version01 FrontrController 코드


Code Link

github.com/mike6321/SpringMVC/commit/b5a571b38aadc80cd4455c40afc69c63bd6ceab7#diff-9b2e6637f4e656d5a2ddc5c37f24c54a159b2da4bc1c01d9460680bda3 4 b36 b7

 

(servlet) FrontController도입 - MyView추가 · mike6321/SpringMVC@b5a571b

Permalink This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. Browse files (servlet) FrontController도입 - MyView추가 Loading branch information Showing 7 changed files with 200 additions an

github.com