MVC 패턴(Model-View-Controller Pattern)
1. 목적
- 업무 로직 및 데이터와 보이는 부분을 분리한다
- 사용자 인터페이스 로직이 비지니스 로직보다 더 자주 바뀐다면 MVC를 사용하는 것이 바람직하다.
- 화면을 포함하는 사용자 인터페이스와 업무 처리 부분을 분리해서 동작할 수 있도록 한다.
- MVC는 원래 Smalltalk 언어에서부터 시작되었으나 현재 GUI를 지원하는 프로그램과 웹프레임워크에서 많이 사용 된다.
요소 | 설명 |
이름 | MVC 혹은 Model-view-Controller |
문제 | 데이터와 해당 데이터를 보여주는 부분의 코드가 섞여 있다. |
해결방안 | 데이터와 뷰를 분리하고 이들을 연동시키는 컨트롤러를 추가한다. |
결과 | Loose coupling(낮은 결합도), 재사용성이 높아진다. 모델만 뷰만 따로 따로 사용이 가능하다. |
2. 설계
- 모델(Model) - 응용프로그램의 데이터를 관리하는 부분 또는 로직(뷰의 모델은 한 개만 있다.)
- 뷰(View) - 데이터를 화면에 보이는 부분을 관리한다. (모델에 대해서 뷰는 여러 개가 있을 수 있다. 테이블 뷰 그래프 뷰 차트 뷰 등)
- 컨트롤러(Controller) - 사용자 입력을 처리하고, Model과 View 사이에서 상호작용을 할 수 있도록 지원한다. (한 개 이상이 있을 수 있다.)
3.MVC의 장점
데이터가 UI로부터 분리되어서 따로 검수하거나 사용하는 것이 가능하다.
4. MVC 패턴의 변형
패시브 모델(Passive Model)
- 컨트롤러만 모델을 조작한다.
- 사용자가 인터페이스를 조작하거나 입력하면 컨트롤러가 모델을 수정한다.
- 모델이 수정된 후에 컨트롤러는 뷰를 업데이트 하도록 요청한다.
- 뷰는 모델에서 데이터를 받아(요청 후) 화면을 업데이트
액티브 모델(Active Model)
- 컨트롤러만이 모델을 수정하는 것이 아니다.
- 모델에서 뷰를 업데이트하도록 요청하는 것이 가능하다.
- 모델이 서브젝트 인터페이스를 제공하고 뷰에서 옵저버로 등록한다.
- 뷰는 모델에서 데이터를 받아 (요청 후) 화면을 업데이트 한다.
Head First
3. 디스플레이 변경(업데이트) -> 뷰가 변경되어야 하는 경우가 있다. (ex. 작업 중이라는 표시를 위해서 모래시계가 나오는 부분등)
마이크로소프트사의 MFC
자바 Swing
- Model/Delegate 구조를 사용한다
- Delegate는 컨트롤러 + 뷰라고 생각하면 된다.
- 자바 스윙 컴포넌트들은 모델과 델리게이트로 구성된다.
- 각 컴포넌트들은 기본적인 기능을 제공하는 디폴트 모델과 델리게이트를 제공한다.
- setModel()과 setUI() 메소드를 이용해서 모델 또는 델리게이트를 변경 가능하다.
5. MVC와 웹
- 사용자가 웹사이트에 접속한다.
- 컨트롤러는 사용자가 요청한 웹페이지를 서비스 하기 위해서 모델을 호출한다.
- 모델은 데이터베이스나 파일과 같은 데이터 소스를 제어한 후에 그 결과를 반환한다.
- 컨트롤러는 모델이 반환한 결과를 뷰에 반영한다.
- 데이터가 반영된 뷰는 사용자에게 보여진다.
6. MVC 패턴의 목적
모델과 뷰의 의존성을 제거한다.
- 모델은 뷰와 상관 없이 바뀔 수 있다.
- 뷰도 모델과 상관 없이 바뀔 수 있다.
Head First
- 사용자는 뷰하고만 접촉가능하다.
- 뷰가 컨트롤러에게 사용자가 어떤 일을 했는지 알려준다
- 컨트롤러에서 모델한테 상태를 변경하라는 요청을 한다.
- 컨트롤러에서 뷰를 변경해달라고 요청할 수 있다.
- 상태가 변경되면 모델에서 뷰에게 그 사실을 알린다.
- 뷰에서 모델한테 상태를 요청한다.
7. MVC 패턴 - (모델 1)
단점: JSP와 엮여 있어서 코드가 조잡하고 수정하기 어렵고 유지보수가 어려움 -> 모델 2를 사용하게 된 계기가 된다.
7. MVC 패턴 - (모델 2)
8. MVC 패턴의 구현 코드 Class diagram
//Student class
public class Student {
private String rollNo;
private String name;
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//StudentView
public class StudentView {
public void printStudentDetails(String studentName, String studentRollNo) {
System.out.println("Student: ");
System.out.println("Name: " + studentName);
System.out.println("Roll No: "+studentRollNo);
}
}
//StudentController class
public class StudentController {
private Student model;
private StudentView view;
public StudentController(Student model, StudentView view) {
this.model = model;
this.view = view;
}
public void setStudentName(){
model.setName(name);
}
public String getStudentName(){
return model.getName();
}
public void setStudentRollNo(){
model.setName(rollNo);
}
public void getStudentRollNo(){
return model.getName();
}
public void updateView() {
view.printStudentDetails(model.getName(), model.getRollNo());
}
}
//MVCPatternDemo class
public class MVCPatternDemo {
public static void main(String[] args) {
Student model = retrieStudentFromDatabase();
StudentView view = new StudentView();
StudentController controller = new StudentController(model, view);
controller.updateView();
controller.setStudentName("John");
controller.updateView();
}
private static Student retrieStudentFromDatabase() {
Student student = new Student();
student.setName("Robert");
student.setRollNo("10");
return student;
}
}
9. MVC 패턴의 장단점
장점
- 클래스간 정보 공유를 최소화시키는 객체 지향 구조
- 모델과 뷰가 서로에 대해서 잘 몰라도 된다.
- 같은 모델에서 여러 개의 뷰를 지원할 수 있다.
단점
- 비효율적일 수 있다
- 뷰가 업데이트 되어야 함을 알려주면, 뷰는 모델로부터 정보를 받아서 업데이트 한다.
- 모델이 뷰가 필요로 하는 것을 직접 전달하는 것이 더 효율적이지만, 객체 지향적이지는 않는다.
- 컨트롤러의 역할이 너무 커질 수 있다.
'Java > 고급객체지향' 카테고리의 다른 글
고급객체지향 프로그래밍 - 템플릿 메소드 패턴(Template Method pattern) (0) | 2021.12.12 |
---|---|
스테이트 패턴(State Pattern) (0) | 2021.12.12 |
고급객체지향 프로그래밍 - 커맨드 패턴(Command Pattern) (0) | 2021.12.12 |
고급객체지향 프로그래밍 - 퍼사드 패턴(Facade Pattern) (0) | 2021.12.12 |
고급객체지향 프로그래밍 - 어댑터 패턴(Adapter Pattern) (0) | 2021.12.12 |