MVC 패턴

MVC 패턴은 소프트웨어 개발 Architecture의 대표적인 방법론 중 하나이다.

MVC의 개념에 대해서는 워낙 좋은 글들이 많으므로 간략하게 적고,

좀 더 실전적인 차원에서 MVC 패턴을 정리해보려고 한다.

MVC 패턴이란?

image

  • 모델(Model), 뷰(View), 컨트롤러(Controller)로 이루어진 디자인 패턴

모델

  • 애플리케이션의 데이터와 관련된 부분
    • 데이터베이스, 상수, 변수 등

  • 사용자 인터페이스 요소(UI)
    • 모델을 기반으로 사용자가 볼 수 있는 화면

컨트롤러

  • 하나 이상의 모델과 하나 이상의 를 잇는 다리 역할
    • 메인 로직을 담당

MVC 흐름

image

  1. 사용자는 원하는 기능을 처리하기 위한 모든 요청을 컨트롤러에게 보낸다
  2. 컨트롤러모델을 사용하고, 모델은 알맞은 비즈니스 로직을 수행한다
  3. 컨트롤러는 사용자에게 보여줄 를 선택한다
  4. 선택된 는 사용자에게 알맞은 결과 화면을 보여준다
  5. 이 때, 사용자에게 보여줄 데이터는 컨트롤러를 통해서 전달받는다

MVC 패턴의 실전 적용

1. Model은 Controller와 View에 의존하지 않아야 한다

  • Model 내부에 Controller와 View에 관련된 코드가 있으면 안 된다
public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.nume = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

2. View는 Model에만 의존해야 하고, Controller에는 의존하면 안 된다

  • View 내부에 Model 코드만 있을 수 있고, Controller 코드가 있으면 안 된다
public class OutputView {
    // 파라미터로 Student 모델 객체를 받음
    public void printProfile(Student student) {
        System.out.println(
            "내 이름은 " + student.getName() + "입니다."
        );
        System.out.println(
            "내 나이는 " + student.getAge() + "입니다."
        );
    }
}

3. Controller는 Model과 View에 의존해도 된다

  • Controller 내부에는 Model과 View의 코드가 있을 수 있다
public class Controller {
    public static void main(String[] args) {
        Student student = new Student("기철", 25);
    }
}

4. View가 Model로부터 데이터를 받을 때, 반드시 Controller를 통해서 받아야 한다

  • View에서 일어나는 ‘과한’ 값 검증과 예외 처리에 주의
  • View에서 일어나는 비즈니스 로직에 주의

5. 올바른 컨트롤러의 예시

  • main()은 MVC에서 Controller의 역할로 가능한 가볍게 구현
  • Controller 내에서 로직은 최대한 배재
  • Model과 View 사이의 연결 역할만 하도록 구현
public static void main(String[] args) throws Exception {
    Players players = InputView.createPlayers();
    Rewards rewards = InputView.createRewards();

    Ladder ladder = LadderFactory.createLadder(players.countOfPeople(), InputView.getHeight())
    OutputView.printLadder(players, ladder, rewards)

    MatchingResult matchingResult = ladder.play();
    LadderResult result = matchingResult.map(players, rewards);

    OutputView.printResult(result);
}

나중에 공부하면 좋을 것들

image

Serive에 대한 이해

  • 비즈니스 로직을 수행하는 메서드를 가지고 있는 객체
  • 비즈니스 메서드를 별도의 Service 객체에서 구현
    • 컨트롤러는 Service 객체를 사용하도록 함

Repository에 대한 이해

  • DAO(Data Access Object)
  • 데이터 엑세스 메서드를 별도의 Repository 객체에서 구현
  • Service는 Repository 객체를 사용

유용한 블로그