들어가며

  • 이전에는 Servlet에서부터 시작된 웹 개발이 JSP가 생겨나면서 Model 1방식이 생겨났고 이것이 어떻게 발전되었는지에 대해 간략하게 설명했다.
  • 이번에는 Model 2방식에서 조금 더 진보한 MVC패턴에 대해 이것이 무엇이고, 각 요소별로 어떤 역할이 있는지에 대해 배운 것을 적어보려고 한다.

 

 

MVC(Model - View - Controller)

  • MVC는 Model, View, Controller로 나누어져 개발하는 일종의 디자인패턴(Design pattern)으로 정의된다.
  • 즉 웹 프로젝트들은 기본적으로 Model 파트와 View파트, Controller 파트로 나누어져 각각의 역할에 맞게 구현되고, 분리되어 저장된다.
  • 최종적으로 이렇게 구현된 각 객체들이 조립되어 사용자의 요청을 처리하고 결과를 보여주는 동작을 수행하게 된다.
  • 각 파트별 무엇을 담당하는지는 아래와 같다.

 

View(뷰)

  • View는 말 그대로, 사용자에게 페이지를 직접 보여주는 역할을 맡은 파트이다. 이곳에서 동적 페이지(JSP, thymeleaf등), 정적 페이지, CSS, JS파일들이 들어간다.
  • View는 오직 사용자에게 입력을 받거나, 처리의 결과를 보여주는 역할에만 충실하며 그 뒤에서 무엇이 일어나는지는 알 필요도 없고, 알 수도 없어야 한다.
    •  Servlet, JSP model 1 방식을 사용할 때는 이 View 영역(JSP영역)에서 DB접근부터 데이터 가공까지 모든 일이 수행되었다. 이는 개발이 편리해지는 장점이 있지만 그만큼 프로젝트의 가독성과 유지보수가 힘들어지는 결과를 발생시키게 되었다.
  • View는 일반적으로 프로젝트에서는 서블릿의 경우 /webapp에 들어가며 동적, 정적파일을 구분하기 위해 static폴더 에네 정적 파일들을 몰아넣게 된다.

 

Controller(컨트롤러)

  • Controller는 사용자의 요청, 입력 등의 변화(event)가 발생할 경우 이러한 변화에 대해 말 그대로 컨트롤 하는 역할을 맡는다.
  • MVC 모델은  이후 설명하겠지만 데이터의 변경, 추가, 삭제등을 담당하는 Model 파트와 위에 서술한 View는 서로의 존재를 알 필요가 없으며 알 수도 없다(정상적으로 구현한 경우)
  • 따라서 만약 Model의 변경이 필요한 이벤트가 View에서 일어난 경우에, 어떠한 경로를 통해서 Model의 변경을 수행해야 하는데. 이 경로를 담당하는 파트가 바로 Controller이다.
  • Controller는 일반적으로는 URL Mapping을 통해 이러한 요청, 입력을 수신받게 된다.(/member/addMember 에 대응되는 컨트롤러가 있을 경우 이 컨트롤러가 해당 url에 대한 처리를 맡게 된다.)
  • View와 Model의 중간다리 역할을 하는 만큼 Controller에서는 View에서 넘어오는 사용자 입력이나 요청을 받고 이를 적절히 가공하여 Model에게 필요한 기능 호출과 함께 입력들을 넘기게 된다.

 

Model(모델)

  • 모델은 웹 어플리케이션의 정보와 데이터에 관한 관리를 담당하며 비즈니스 로직에 의한 데이터 처리 결과를 DB, 또는 특정 저장소에 반영하고, Controller와 View에 전달한다.
  • 모델은 View에 제공할 데이터들을 저장하고 있다가 이후 View에서 해당 데이터들이 필요할 시 가져갈 수 있도록 해준다.(정확히는 뷰 템플릿에서 모델 내부의 데이터들을 가져간다.)
  • Controller는 받은 데이터를 적절히 가공하여, View에서 사용할 수 있도록 만들고, View에 해당 결과를 보내준다. View는 해당 결과를 페이지에 적절히 출력하여 사용자에게 정보를 보여주게 된다.

 

 

 

Domain과 DTO

  • MVC 패턴에서 어떻게 데이터를 DB에 추가하는지는 Model의 DAO를 통해 수행한다는 것을 보았다. 그렇다면, DAO는 무엇을 기반으로 DB와 통신하여 데이터를 처리하는 것인가라는 의문이 생긴다.
  • 즉 Java로 따지자면 JDBC를 통해 DB와 통신하는데 무엇을 통해 DB에 데이터를 넣거나, 찾는 처리를 수행할 것인가이다. 이는 DB의 Table을 나타내는 어떠한 객체가 있으면 좋아 보인다.
  • 만약 회원 테이블이 DB에 존재하고 이 테이블의 컬럼이 id와 이름으로 되어있다고 한다면 이를 프로그래밍 언어로 관리하기 위해서는 각 컬럼을 멤버 변수로 갖는 하나의 클래스가 좋아보인다. 코드로 나타내면 이럴 것이다.
public class Member{
    private int id;
    private String name;
    
    public int getId(){
    	return this.id;
    }
    
    public String getName(){
    	return this.name;
    }
}
  • 이렇게 DB의 테이블을 표현한 것을 도메인(Domain)이라고 한다.
  • private 접근제한자를 통해 외부에서 특정 메서드를 통하지 않고서는 접근하거나 수정할 수 없도록 제한시켰다.
  • 그런데 사용자의 입력을 받아 DB에 넣어야 하는 경우에 이 Member 도메인의 값을 수정하거나, 추가해야할 일이 발생할 수 있다. 여기서는 get을 통한 데이터를 가져오는 메서드만 구현되어 있으므로 값을 설정하거나 추가하는데 필요한 객체가 추가적으로 필요해 보인다.
public class MemberDTO{
    private int id;
    private String name;
    
    public int getId(){
    	return this.id;
    }
    
    public String getName(){
    	return this.name;
    }
    
    public void setId(int id){
    	this.id = id;
    }
    
    public void setName(String name){
    	this.name = name;
    }
}
  • 이 객체는 데이터를 수정할 수도 있다. 따라서 데이터를 Model로 넘기거나, Controller로 넘길 때 수정할 사항이 생길 경우 수정하고 전송할 수 있다.
  • 이 객체를 DTO(Data Transfer Object)라고 한다. 즉 데이터를 수송하는 역할을 담당하는 객체이다.
  • Controller에서 Model로 전송하는 데이터는 일반적으로 이런 DTO에 캡슐화되어 전송되며 그 역도 동일하다. 또한 Controller에서 Model의 데이터를 View로 넘겨야 할 때도 DTO를 사용하게 된다.
복사했습니다!