MVC 패턴

MVC는 왜 생겨난걸까?

(MVC가 생겨나게 된 배경가 이유를 알게 되면, MVC의 핵심을 파악할 수 있게 된다.)

과거의 많은 사람들이 코딩을 했었는데 코드가 많아지면 많아질수록 코드가 복잡해졌다. 코드를 복잡한 채로 놔두니 나중에 기능 수정 및 변경이 일어날 때마다 코드를 파악하기도 힘들고, 어떤 기능을 살짝 수정하려고 했는데 대부분의 코드를 수정해야 하는 경우가 빈번했다. 즉, ‘유지보수’가 불편했다. 그러다가 코딩을 잘하는 사람들이 코드를 짜다보니 효율적으로 코드를 구성할 수 있는 패턴들이 생겼었다. 여기서 효율적으로 코드를 구성한다는 것은 ‘유지보수’가 편하다는 뜻이다. 그래서 그 패턴을 하나의 ‘공식’처럼 만들어서 논문으로 발표하게 됐다. 그렇게 소프트웨어 설계자들 사이에서 유명한 패턴인 MVC가 탄생하게 됐다.

요약하자면, 유지보수를 편하게 할 수 있는 패턴 중 하나가 MVC인 것이다.

유지보수가 편한 코드란?

유지보수가 편한 코드라는 뜻은, 특정 기능을 추가 및 변경할 때 가능한 한 최소한의 코드만을 수정해서 기능을 변경할 수 있음을 의미한다. 최소한의 코드만을 수정해서 기능을 변경하려면, 변하는 것과 변하지 않는 것을 분리해야 한다. SOLID, 전략 패턴, State 패턴, MVC 패턴 등 대부분의 디자인 패턴이 ‘변하는 것과 변하지 않는 것을 분리’해서 유지보수를 편하게 하려고 한다. 즉, ‘변하는 것과 변하지 않는 것을 분리’하는 것이 디자인 패턴의 핵심이다.

MVC 전체 구조 맛보기

MVC의 전체 구조를 웹에 비유해서 이해해보자.

image

위의 예시를 일반화해서 정리하면, 사용자가 Controller를 조작하면, Controller는 Model에 명령을 보내고, Model이 View에 데이터를 전달하고, View가 전달받은 데이터를 바탕으로 시각적으로 표현을 한 후 사용자에게 전달한다.

Model, View, Controller의 1줄 요약

  • Model : 데이터
  • View : 사용자한테 보여주는 부분 + 데이터
  • Controller : Model과 View를 활용해 전체 로직을 작성하는 곳

MVC를 지키려면…

**참고) A가 B에 의존하다. = A에 B에 관련된 코드가 있다.

Model

  • Model은 Controller와 View에 의존하지 않아야한다. **(= Model 클래스 내부에 특정 Controller 클래스의 코드와 특정 View 클래스의 코드가 있으면 안 된다.)

View

  • View는 Model에만 의존해야하고, Controller에는 의존하면 안 된다. (= View 클래스 내부에 Model 클래스의 코드만 있고, 특정 Controller 클래스의 코드가 있으면 안 된다.)
  • View가 Model로부터 데이터를 받을 때에는 직접 받으면 안 되고, Controller를 통해서 받아야 한다.
  • View가 Model로부터 데이터를 받을 때는, 사용자마다 다르게 보여주어야 하는 데이터에 대해서만 받는다.

Controller

  • Controller는 Model과 View에 의존한다. (= Controller 클래스 내부에 Model 클래스, Controller의 클래스의 코드가 있다.)
  • Controller는 Model의 데이터를 받아서 View로 전달해주어야 한다.

예제

Model

public class Student {
    private String name;
    private int age;

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

    public int getAge() {
        return age;
    }
}

View

public class OutputView {
    public void printProfile(Student student) {
        System.out.println(
            "내 이름은 " + student.getName() + "입니다.");
        System.out.println(
            "내 나이는 " + student.getAge() + "입니다.");
    }
}

Controller

public class Controller {
    public static void main(String[] args) {
        Student student = new Student("기철", 25);
        OutputView.printProfile(student);
    }
}

콘솔 결과

image

MVC의 장점

Model, View, Controller가 분리되어 있어서, 내가 필요한 부분만 쉽게 찾아내거나 수정할 수 있게 된다. 예를 들면, 나이를 조회하는 getAge() 메서드에서 한국 나이 계산법에서 미국 나이의 계산법으로 바꾸고자 할 때, View와 Controller 부분은 신경쓰지 않고 수정이 필요한 Model의 코드만 수정하면 된다. 또한 데이터와 로직은 그대로 사용하는데, 사용자한테 보여주는 부분의 디자인을 변경하고자 할 때, Model과 Controller 부분의 코드를 건드리지 않고 View의 코드만 수정하면 되므로 훨씬 코드를 읽기도 쉽고 수정하기도 쉬워진다.

Q&A

Q. MVC라는 개념이 백엔드에만 적용되는 개념인가요 ?

A. 소프트웨어를 설계하는 곳에 전반적으로 활용되는 개념이다.

  • 백엔드의 관점으로 봤을 때에는 Model을 데이터를 관리하는 데이터베이스, Controller를 사용자로부터 요청을 받아 로직을 처리하는 곳, View를 사용자의 요청에 대한 응답을 하는 곳이라고 생각할 수 있다.
  • 프론트엔드의 관점으로 봤을 때에는 Model을 백엔드로부터 받은 데이터를 관리하는 곳, Controller를 사용자로부터 받은 이벤트들을 처리해서 Model과 View를 연결시켜주는 역할을 하는 곳, View를 HTML, CSS와 같이 사용자에게 보여주는 화면을 꾸미는 역할을 하는 곳이라고 생각할 수 있다.
  • 백엔드, 프론트엔드를 통틀어서 봤을 때에는 백엔드가 Model과 Controller의 역할을 하고, 프론트엔드가 View의 역할을 한다고 볼 수 있다.

이와 같이 MVC는 여러 소프트웨어 설계 방식에 녹아들어져있다.

Q. MVC는 만능인가요 ?

A. MVC도 단점을 가지고 있다. Controller에 Model과 View의 코드가 모여있다보니, 프로젝트의 규모가 커지면서 Controller가 너무 비대해져서 복잡성이 증가한다. 이로 인해 유지 보수가 어려워지고 가독성이 떨어지게 된다. 이러한 문제점을 보완하기 위해 MVC 이외에 MVVM, MVP 등의 다양한 패턴들도 있다.

어떤 아키텍처든 만능은 없다. 적재적소에 잘 활용하는 것이 중요하다. 극단적인 예로, 아주 적은 양의 코드만을 필요로 하는 프로그램이면서 한 번 쓰고 버릴 코드라면 MVC라는 패턴따위는 신경쓰지 않고 하나의 파일에 뭉터기로 코딩하는 것이 효율적인 방식일 것이다.

References