본문 바로가기
Web/공부

[Spring] MVC 패턴과 Service, Domain, Repository

by 소똥 2023. 9. 6.
MVC 패턴을 공부를 했으나, 막상 프로젝트를 생성하고 코드를 구조화하여 작성하려하니 MVC가 어떻게 적용되는 거지?! 라는 의문이 들었다. 또 많은 타 프로젝트에서 Controller, Service, Domain, Repository 로 패키지가 나누어져 있는데, 이녀석들은 또 MVC의 어디에 포함되는것인가. DTO, DAO는 또 어디에 껴들어가는 것인가!?

이론적으로 알던것들과 실질적인 코드가 따로 노는것 같아 내가 이해한바를 정리하여 작성해보고자 한다.

 

MVC 패턴 이란?

소프트웨어 디자인 패턴 중 하나로,

애플리케이션을 Model-View-Controller의 구성요소로 분리함으로써 구조화하고 재사용하기 편하게 만든 패턴.

 

역사

객체지향의 아부지 앨런 케이가 활동하던 연구소인 제록스 팔로 알토 연구소에서 린스케이지(Trygve Reenskaug) 에 의해 개발된 패턴이다.

최초의 태블릿 PC를 개발하던 중, CLI가 아닌 GUI 기반의 직관적인 UI를 만들기 위하여 고민하게 되는데,,, 그에 대한 돌파구로 'UI 관련 코드'와 '데이터 저장 코드', 둘사이 연결점 을 분리하고 역할을 부여하도록 분리하게 된다. 고것이 바로 MVC의 시작!

 

즉, MVC의 본질은 관심사의 분리 ! (Separation of Concerns)

 

++ 인프런 MVC 강의를 통해 습득한 내용. 

1. 원래는 MVC 패턴 적용 없이, 서블릿만으로 코드를 작성했다고 한다. 

@WebServlet(name = "memberServlet", urlPatterns = "/servlet/members/new-form")
public class MemberFormServlet extends HttpServlet {
    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");

        PrintWriter w = response.getWriter();
        w.write("<!DOCTYPE html>\n" +
                "<html>\n" +
                "<head>\n" +
                " <meta charset=\"UTF-8\">\n" +
                " <title>Title</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<form action=\"/servlet/members/save\" method=\"post\">\n" +
                " username: <input type=\"text\" name=\"username\" />\n" +
                " age: <input type=\"text\" name=\"age\" />\n" +
                " <button type=\"submit\">전송</button>\n" +
                "</form>\n" +
                "</body>\n" +
                "</html>\n");
    }

}

 

2. JSP 방식 도입. 

이 경우, 반대로 html에 java를 넣는 방식!

<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    MemberRepository memberRepository = MemberRepository.getInstance();
    List<Member> members = memberRepository.findAll();
%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="/index.html">메인</a>
<table>
    <thead>
    <th>id</th>
    <th>username</th>
    <th>age</th>
    </thead>
    <tbody>
    <%
        for (Member member : members) {
            out.write(" <tr>");
            out.write(" <td>" + member.getId() + "</td>");
            out.write(" <td>" + member.getUsername() + "</td>");
            out.write(" <td>" + member.getAge() + "</td>");
            out.write(" </tr>");
        }
    %>
    </tbody>
</table>
</body>
</html>

3. 그럼에도,,,  아래와 같은 문제로 인해 MVC 등장!!

  • 너무 많은 역할 —> 비즈니스 로직을 호출 / ui 변경 등 계속 파일 수정해야함
  • 변경 라이프 사이클이 다름
  • 기능 특화


MVC 각각 살펴보기

  • Model 
    데이터와 비즈니스 로직을 관리.
    비즈니스 로직이란, 애플리케이션에서의 핵심적인 목적을 가진 기능을 구현한 놈! 이라고 이해하였다.
    예를들어 회원관리 서비스에서 join, login, logout

  • View
    레이아웃과 화면을 처리
    프론트 엔드단이라고 이해하면 될것 같다. javascript로 만들어진 UI부가 View.

  • Controller
    사용자 입력을 처리하고 모델과 뷰의 인터페이스 역할을 수행
    이녀석은 아래 파트에서 이해를 돕기위한 구조도를 추가하겠다!

 

어떻게 동작하는가?!

아래 그림과 같이,

클라이언트로부터 받은 요청을 비즈니스 로직(by Model)을 거친 후, 다시 클라이언트에게 응답 (by View) 한다.

 

 

어떻게 사용되는가?

이제, 내가 의문을 가졌었던! 그럼 MVC 각각이 프로젝트 구조에서 어떻게 반영되어 있는것인가!

 

우선 내가 공부 및 사용하고 있는 프로젝트 구조는 아래와 같다.

ㄴ main
	ㄴ java
            ㄴ controller
                MemberController
            ㄴ domain
                Member
            ㄴ repository
                MemberRepository
            ㄴ service
                MemberService
  • Controller
    HTTP 메서드 요청이 오면, 필요한 로직을 수행하게 된다.
    이때 domain에 정의된 Member 객체로 받아서 service의 join / login 등의 함수를 사용하여 로직을 수행한다. 
    필요시 service단에서 전달된 데이터를 프론트단에 응답 하게된다. 

  • Domain
    객체의 상태 변화에 대한 정보를 담고 있다. 
    여기서,, 어쩔때는 DTO를 사용하고, 어쩔때는 Entity 이거 무슨 차이냐!? 또 찾아보면 DTO와 Entity 분리해야 한다고 하는데,, 똑같은거 아니었어?! (분리에 대한 내용은 나중에 다루겠다!)

    결론은 아니다! 
    DTO는 이름에서도 알수있듯 데이터 전달시 구조를 제공하는 녀석으로, 웹에서 클라이언트 서버간 데이터 주고받을때 사용된다.
    Entity 클래스는 DB 와 관련이 있으며, DB 저장하고 조회 등 비즈니스 로직 수행시 사용되는 객체이다.

  • Repository
    DB와 상호작용을 한다. 엔티티 객체를 DB 테이블에 맵핑함으로써 CRUD 작업을 수행한다.
  • Service
    애플리케이션의 핵심 비즈니스 로직을 담고 있는 모듈
    controller로부터 받은 데이터로 엔티티와 상호작용하고 데이터를 가공하게 된다.
    이녀석이 MVC의 Model에서의 핵심

 

결론

내가 이해한 바는 아래와 같다. 

결국, 나눠보자면 Controller는 MVC의 C 의 역할을 수행하고 있고, 서비스-리포지토리는 M의 역할을 수행하고 있다.

V는 html, js 등으로 구성된 녀석들이라고 할 수 있겠다.

 

추가로, Domain은 MVC에 매칭되기보다는 DTO, 엔티티 등 데이터의 구조와 관련이 있는 녀석이다.

 

MVC 패턴은 그냥 소프웨어의 아키텍처일 뿐, 프로젝트 구조에서 1:1 대응이 되는 것도 아니고 단지 이 패턴이 효율적으로 적용될 프로젝트라면 고려하며 구조를 설계하면 되는 것이다!



참고) 
MVC : https://developer.mozilla.org/ko/docs/Glossary/MVC
MVC : https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
MVC의 역사 : https://developer.mozilla.org/ko/docs/Glossary/MVC
DTO와 Domain : https://umbum.dev/1206

'Web > 공부' 카테고리의 다른 글

[Java/Spring] JSON 파싱하기  (0) 2023.09.01
[Web/CS] HTTP 통신에 대한 모든 것  (0) 2023.08.28