스프링 | 스프링 부트

MVC 패턴이란?

Adose 2025. 1. 21. 15:51

📘MVC 패턴이란?

model, view, controller로 애플리케이션을 3가지 역할로 분리하여 개발하는 소프트웨어 설계 패턴 중 하나이다.

1️⃣ Controller 란?

  • 사용자의 요청(Request)을 처리하고, 적절한 응답을 반환한다.
    • 요청에 따라 사용자의 입력을 Model에 전달하고, 비지니스 로직 결과를 View로 전달
  • Model과 View의 다리 역할이라고 생각하면 된다.

⚒️ Controller 규칙

  • Model과 View에 의존해도 된다.
  • Controller 내부에 Model, view의 코드가 있을 수 있다.

public class TestController {
    @GetMapping("/test")
    public String getTest(Model model) {
        Test test = new Test("testData", "hihi");
        model.addAttribute("test", test);
        return "testView";
    }
}
  • 위에서 Model(Spring 객체)은 데이터를 view로 전달하기 위해 사용되는 도구이다.
    • import org.springframework.ui.Model;

2️⃣ Model 이란 ?

❔ Spring의 Model 객체, 비즈니스 로직을 가진 Model 을 구분해서 설명한다


📎 Spring의 Model 객체

  • Spring 에서 제공하는 Model 객체는 데이터를 view로 전달하기 위해서 사용되는 도구이다.
    • import org.springframework.ui.Model;
  • 데이터를 View로 전달하기 위해 키-값을 사용하는 방식이다.
  • 아래 코드에서는 test 라는 키(key)를 통해 View에서 데이터를 꺼내 쓸 수 있습니다.
public class TestController {
    @GetMapping("/test")
    public String getTest(Model model) {
         String test = "hi testest"//데이터 생성 
        model.addAttribute("test", test); //데이터를 모델 객체에 전달 
        return "testView";  //testView.html로 전달 
    }
}
<!-- "testView.html이 실행된다."  -->
<!DOCTYPE html> 
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Test</title>
</head>
<body>
    <h1 th:text="${test}"></h1> <!-- "hi testest" 이 출력된다.  -->
</body>
</html>

📎 비즈니스 로직을 가진 Model

  • Controller에게 받은 데이터를 데이터베이스와의 상호작용(데이터 가공, 처리하는 로직), 비즈니스 로직을 통해 가공한다.
  • 사용자가 요청한 데이터를 비지니스 로직을 처리한 후 Controller나 View에 전달.

⚒️ Model 규칙

  • controller와 view 에 대해서 어떤 정보도 알지 못한다.
  • model에 controller와 view와 관련된 코드가 있으면 안된다.
  • view가 Model로 부터 데이터를 받을때, Controller에서 받아야 한다.

public class Test {
    String name;
    String data;

    public Test(String name, String data) {
        this.name = name;
        this.data = data;
    }

    // 비즈니스 로직 추가 (!가 포함되어져 있다면 true return) 
    public boolean isValidData() {
        return data.contains("!");
    }
}

@Service
public class Testervice {
    private final TestRepository userRepository;

    public TestService(TestRepository testRepository) {
        this.testRepository = testRepository;
    }

    // 비즈니스 로직: test 등록 
    public void registerTest(Test test) {
        if (!test.isValidData()) {
            throw new IllegalArgumentException("Invalid email address");
        }
        testRepository.save(test);
    }
}

3️⃣ View 란?

  • View(뷰)는 사용자에게 데이터를 보여주는 역할을 한다.
    • 서버에서 데이터를 받아서 시각적으로 표현한다.
  • Thymeleaf, JSP 같은 템플릿 엔진이 View에 해당한다.

⚒️ View 규칙

  • View는 모델에만 의존해야하고, Controller에 의존하면 안된다.
  • view내부에 Model의 코드가 있을 수 있지만, Controller의 코드가 존재하면 안된다.

  • 아래 코드는 Thymeleaf(타임리프) 예시이다.
<!-- "testView.html이 실행된다."  -->
<!DOCTYPE html> 
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Test</title>
</head>
<body>
    <h1 th:text="${test}"></h1> <!-- "hi testest" 이 출력된다.  -->
</body>
</html>

📘 MVC 흐름

  1. 사용자가 브라우저를 통해 요청(Request)을 보냄.
  2. Controller가 요청을 받아 처리.
  3. Model에서 데이터를 가져오거나 가공.
  4. Controller는 Model에서 받은 데이터를 View에 전달.
  5. View는 데이터를 기반으로 사용자에게 응답(Response)을 반환.

📘 MVC 장점 ?

1. 컴포넌트의 명확한 역할 분리로 인해 서로간의 결합도를 낮출 수 있다.
2. 코드의 재사용성 및 확장성을 높일 수 있다.
3. 서비스를 유지보수하고 테스트하는데 용이해진다.
4. 개발자 간의 커뮤니케이션 효율성을 높일 수 있다.

1️⃣ 컴포넌트의 명확한 역할 분리로 인해 서로간의 결합도를 낮출 수 있다

MVC패턴은 Model, View, Controller 3가지 컴포넌트로 구분되어 있다. Model은 비즈니스 로직, View 는 사용자 인터페이스, Controller는 사용자의 요청을 통해 Model, View의 흐름을 제어한다.

📖 이러한 점을 통해 각각의 컴포넌트(MVC)는 자신이 맡은 역할만 수행한 후 다른 컴포넌트로 결과만 넘겨주면 되기 때문에 서로간의 결합도를 낮출 수 있다.

2️⃣ 코드의 재사용성 및 확장성을 높일 수 있다.

개발한 Model과 Controller는 여러 View에서 재사용할 수 있고, View의 경우도 다른 Model과 함께 재사용할 수 있으므로 개발 시간을 단축하고 중복 코드를 줄이는데 많은 도움을 줄 수 있다.

📖 기능별로 코드분리하여 하나의 파일에 코드가 모이는 것을 최소화하여, 작성한 코드의 가독성 및 확장성, 그리고 재사용성을 증가시킬 수 있다.

3️⃣ 서비스를 유지보수하고 테스트하는데 용이해진다.

변경이 필요한 부분을 보다 쉽게 식별 및 파악할 수 있고, 수정이나 확장할 경우 해당 부분에만 집중하여 개발할 수 있어, 다른 부분에는 영향을 덜 주게 된다. 이를 통해 변경에 따른 유지보수 비용을 줄일 수 있다.

📖 Model, View, Controller개별적으로 테스트하기 쉽기 때문에 컴포넌트의 동작을 테스트하기 위한 단위테스트 및 통합 테스트 코드를 개발하는데 수월하다.

4️⃣ 개발자 간의 커뮤니케이션 효율성을 높일 수 있다.

Model, View, Controller의 역할이 분리되어 있기 때문에 개발자들 간의 협업 과정 속에서도 담당한 역할에 대한 작업을 수행하면 되기 때문에 코드 충돌을 미리 방지하기가 쉽다.

📖 분리된 역할마다 개발자가 배정되어 개발 업무를 수행하기 때문에 제 3자인 개발자가 의견이나 피드백을 전달하기 좋은 구조를 제공하며, 보다 쉽게 새로운 요구사항을 도출할 수 있다.

➕ 참고자료

https://velog.io/@langoustine/여기도-MVC-저기도-MVC-MVC-패턴이-뭐야#mvc는-왜-생겨난-걸까