MVC 프레임워크 만들기 #1 - FrontController, View 분리, Model 추가

Ryu·2023년 1월 2일
0
post-thumbnail

[ 시작하기 앞서... ]


왜 기록을 하는가 ?

요즘 드는 생각은, 이렇게 정리하고 기록해도 '반복'해서 보지 않는다면 결국 기억에서 휘발된다는 것이다. 특히, 최근 부트캠프와 같은 외부 교육을 수강하면서 짧은 기간에 압축적으로 배울 때는 더더욱 휘발성이 심한 것 같다.
아직 배울 게 많고 늘 부족하다고 생각해 Notion 에 먼저 정리를 해두고, 블로그에 다시 정리해서 올리는 편인데 이 방식이 생각보다 시간이 많이 걸려서 꾸준히 글을 작성하지 못했다.
그러나 이러한 방법이, '반복'을 해야한다는 측면에서는 내 생각을 다시 정리해보고 이미 했던 것을 복기해본다는 측면에서는 매우 좋은 방식일 것 같다는 생각이 든다.
만약 본인이 글을 쓰는 사람이라면 왜 글을 쓰는지 깊게 고민해보는 것도 좋은 동기부여가 될 수 있을 것 같다!!

[ Front Controller ]


어떤 식으로 구현했나

  • 이번 프로젝트에서 구현한 프론트 컨트롤러는 http 요청을 받아서 , 이에 맞는 컨트롤러를 찾아서 호출한다.
    • 실제 구현은, hashMap 에 매핑 url 과 구현 컨트롤러를 저장하는 방식으로 진행하였다.
  • Front Controller 클래스만 Servlet 역할(매핑 url 요청 파라미터 정보를 파싱해서 가져오는..)을 수행한다.
    • 이 덕분에, 구현 Controller 들에서는 @WebServlet 을 없애줄 수 있었고 Servlet 관련 처리에 대한 로직들이 모두 FrontController 에 있기 때문에 유지, 보수도 수월해졌다.
    • 항상 느끼는건데, '중복'하는 부분에 대한 제거를 효율적으로 할수록 유지/보수가 쉬운 코드가 된다. (변경의 지점을 하나로 가져갔기 때문..)

View 분리 이유

  • 이 역시 중복 때문이다. Controller 단에서 View 에 대한 경로를 하나하나 모두 써주고 있었다.

변경 후

  • Controller 는 이제 MyView 만 반환하고, MyView 가 랜더링을 담당한다.
  • 이렇게 객체지향처럼 각자 역할을 수행하도록 독립적으로 설계하는 것이 매우 매우 중요하다. 왜 ? 이렇게 설계 해야 추후 변경할 때 다른 코드들이 영향 받지 않는다.

Controller 를 interface 로 구현한 이유

구현 컨트롤러는 Controller interface 의 메서드 하나만 상속받는데, 굳이 왜 interface 로 만들었을까 ?

  • 간단하다. FrontController 에서 '갈아 끼울 수 있게' 하기 위해서다.
  • 인터페이스를 구현해서 메서드 오버라이딩 하면, 기존 인터페이스 타입의 객체 변수를 새로운 구현 객체로 갈아 낄 수 있는 코드를 작성할 수 있다...

Model 추가한 이유

  • 현재는 구현 Controller 가 서블릿에 종속적이다. (서블릿 예외 처리 코드나, 메서드 안에 HttpServletRequest 와 같은 객체가 존재함)
  • 어차피 FrontController 에서 공통처리를 해주고, 서블릿의 기능을 수행하기 때문에 굳이 하위 클래스에까지 쓸 필요가 없다.
  • ModelView 라는 String viewName 과 model(HashMap) 을 변수로 갖는 클래스를 만들었다. -> 이제 Controller 에서 이를 반환한다.

ModelView 클래스 구현 과정

  • String viewName, model(HashMap) 을 변수로 갖고 있다.
  • Controller 에서는 이제 paramMap 이라는 파라미터를 통해 파싱 정보를 저장한다. (paramMap 역시 HashMap)
  • 이 paramMap 에 요청 파라미터 정보를 넣어주는 작업은 당연히 Servlet 인 FrontController 에서 수행한다.
  • viewResolver() : 경로의 '공통' 부분을 FrontController 에서 넣어주고, 그 외 부분은 ModelView 의 생성자로 만들게끔 구현.
    private MyView viewResolver(String viewName) {
            return new MyView("/welcome/views/" + viewName + ".jsp");
        }
profile
Strengthen the core.

0개의 댓글