우아한테크코스 제리의 MVC 패턴을 듣고 정리한 글입니다.
MVC 패턴의 탄생 배경
과거의 프로그래머들은 수많은 프로그램을 만들었다. 하지만, 코드가 많아질수록 복잡해져 코드가 파악하기 힘들고 기능을 수정할 때마다 대부분의 코드를 갈아엎어야 하는 경우가 많았다. 즉, 유지보수가 하기 어려웠다. 그러다 계속 코드를 짜다 보니, 특정 코드 구성을 하니 유지보수가 편한 것을 발견하게 됐다. 이러한 규칙성이 조금씩 보이기 시작했다. 그리고 이 패턴을 공식처럼 만들어 논문으로 발표하게 됐고, 많은 프로그래머들의 사랑을 받아 오늘날의 MVC 패턴이 생겨나게 되었다.
MVC는 유지보수가 편해지는 코드 구성 방식이라고 할 수 있다.
MVC를 웹에 비유해서 맛보기
- 사용자가 구글에 코딩이라고 검색을 한다.
- 컨트롤러는 코딩에 대한 검색 결과 데이터를 모델에게 요청한다.
- 모델은 검색 결과 데이터를 찾아서 컨트롤러에게 전달하고
- 컨트롤러는 뷰에게 전달한다.
- 뷰는 UI 검색 결과 데이터를 나눠서 사용자에게 전달한다.
모델은 데이터를 가지고 있는 곳, 컨트롤러는 모델과 뷰의 중개자 역할을 한다. 뷰는 사용자한테 보이는 부분을 담당하는 곳이라고 간단하게 생각할 수 있다.
Model, View, Controller
모델(Model)은 데이터와 관련된 부분이고, 뷰(View)는 사용자한테 보여지는 부분, 컨트롤러(Controller)는 Model과 View를 이어주는 부분이다.
MVC를 지키면서 코딩하는 방법
죽어있는 이론이 되는 것을 막기 위해서, 적용하는 방법을 알아보자.
1. Model은 Controller와 View에 의존하지 않아야 한다.
Model 내부에 Controller와 View에 관련된 코드가 있으면 안 된다. 즉, Model 클래스에서 Controller와 View의 클래스를 import해서 사용하면 안 된다. 제리가 말하기로는 Model은 데이터와 관련되어 있어 언제나 깔끔하고 정제된 데이터를 꺼내 쓸 수 있도록 View나 Controller의 코드를 섞어서 넣지 않고, 데이터와 관련된 코드만 깔끔하게 모아놓으려고 했을 수 있다고 한다.
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;
}
}
위와 같은 학생 클래스는 Controller와 View에 의존하지 않는다.
2. View는 Model에만 의존해야 하고, Controller에는 의존하면 안된다.
View 내부에 Model의 코드만 있을 수 있고. Controller의 코드가 있으면 안 된다. 즉, View 내부에 Model의 코드만 있을 수 있다. 하지만, Controller의 코드가 있으면 안된다.
public class OutputView {
public void printProfile(Student student) {
System.out.println(
"내 이름은 " + student.getName() + "입니다.");
System.out.println(
"내 나이는 " + student.getAge() + "입니다.");
}
}
3. View가 Model로부터 데이터를 받을 때는, 사용자마다 다르게 보여주어야 하는 데이터에 대해서만 받아야 한다.
배달의 민족 주문하기 페이지처럼, 사용자마다 다르게 보여주어야 하는 부분이 있다. 정리하자면 View는 사용자한테 보이는 UI와 Model로부터 받은 데이터가 합쳐져서 만들어진다. 모든 사용자에게 똑같이 보여야 하는 부분은 Model로부터 데이터를 받으면 안 된다. (View가 자체적으로 가지고 있어야 할 데이터이다.)
4. Controller는 Model과 View에 의존해도 된다.
Controller 내부에는 Model과 View의 코드가 있을 수 있다.
public class Controller {
public static void main(String[] args) {
Student student = new Student("기철", 25);
OutputView.printProfile(student);
}
}
5. View가 Model로부터 데이터를 받을 때 , 반드시 Controller에서 받아야 한다.
위의 Controller 코드를 보면, Controller 코드 내에서만 View가 Model로부터 데이터를 받을 수 있다.
MVC 적용해보기
MVC 규칙을 지키지 않은 코드
public class Car {
private static final String ONE_STEP = "-";
public Result move() {
...
OutputView.printResult(ONE_STEP); //1번 규칙 위반
return result;
}
}
public class OutputView {
public static void printResul(String step) { //3번 규칙 위반, 5번 규칙 위반
System.out.println(step);
}
}
public class GameManagerController {
public void play() {
InputView.inputCarNames();
...
car.move();
}
}
아래는 MVC 규칙을 지킨 코드이다.
public class Car {
public Result move() {
...
return result;
}
}
public class OutputView {
private static final String ONE_STEP = "-";
public static void printResult(Result result) {
System.out.println(ONE_STEP);
}
}
public class GameManagerController {
public void play() {
InputView.inputCarNames();
...
Result result = car.move();
OutputView.printResult(result);
}
}
3번 규칙에 따르면, View는 Model로부터 사용자마다 다르게 보여줘야 하는 데이터에 대해서만 받아야 한다. 하지만, MVC 규칙을 지키지 않은 코드를 보면 OutputView의 printResult 메서드의 파라미터로 모든 사용자에게 똑같이 보이는 부분을 보냈다. 즉, 3번 규칙을 위반한다. 또한 Controller에게 Model로부터 온 데이터를 받는 것이 아니기 때문에 5번 규칙 또한 위반된다.
또한 1번 규칙에 따르면, Model 내부의 Controller와 View에 관련된 코드가 있으면 안 된다. 하지만 Model에 해당하는 Car 클래스를 보면, move 메서드 내부에서 View 관련 코드인 OutputView.printresult 코드가 있다. 즉 1번째 규칙을 지키지 않았다.
'맛있지만 저작권 문제 > 테코톡' 카테고리의 다른 글
[테코톡 정리] 어썸오의 JVM Memory Layout (0) | 2022.11.12 |
---|---|
[테코톡 정리] 오리와 코린의 Merge, Rebase, Cherry pick (1) | 2022.11.05 |