FIF's 코딩팩토리

MVC 패턴(MVC Pattern) 정리 본문

Back-End/Design Pattern(디자인 패턴)

MVC 패턴(MVC Pattern) 정리

FIF 2019. 6. 10. 15:16
반응형

MVC 패턴 정의

모델-뷰-컨트롤러(Model-View-Controller)는 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴이다.   

이 패턴을 성공적으로 사용하면, 사용자 인터페이스로부터 비즈니스 로직을 분리하여 애플리케이션의 시각적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이 쉽게 고칠 수 있는 어플리케이션을 만들 수 있다.

 

 

View

- 모델을 표현하는 방법을 제공하는 사용자 인터페이스.

일반적으로 화면에 표시하기 위해 필요한 상태 및 데이터를 모델에서 직접 가져온다.

 

Model

- 모든 데이터, 상태 및 어플리케이션 로직이 들어있다.

뷰와 컨트롤러에서 모델의 상태를 조작하거나 가져오기 위한 인터페이스를 제공하고 모델에서 자신의 상태 변화에 대해서 옵저버들에게 알려주긴 하지만 기본적으로 모델은 뷰와 컨트롤러에 대해 별 관심이 없다.

 

Controller

- 뷰와 모델 사이에 위치하며 사용자로부터 입력을 받아 그것이 모델에게 어떤 의미가 있는지 파악한다.

단순히 모델한테 전달하는 역할만 하는 것이 아니라 사용자가 입력한 것을 분석하여 그것을 바탕으로 모델을 조작하는 임무를 맡고 있다.

 

- 뷰에서 컨트롤러의 역할을 직접 맡아도 되지만, 그렇게 하지 않는 것이 좋다.

첫 번쨰로 뷰가 두 가지 역할을 맡기 때문에 코드가 복잡해지고 유지보수에도 좋지 않다.

두 번째로 뷰를 모델에서 너무 밀접하게 연관시켜야 한다는 문제가 있다.

때문에 뷰를 다른 모델하고 연결해서 재사용하기가 어려워 진다.

 

- 컨트롤러는 뷰와 모델의 결합을 끊어주는 역할을 한다.

뷰와 컨트롤러는 느슨하게 결합시켜 놓으면 더 유연하고 확장하기 좋은 디자인을 만들 수 있다.

 

* 사용자는 뷰하고만 접촉할 수 있다.

- 뷰는 모델을 보여주는 창이라 할 수 있다.

재생 버튼을 누른다든가 하는 식으로 뷰에 대해서 어떠한 행동을 하면 뷰에서 컨트롤러한테 사용자가 어떤 일을 했는지 알려준다.

 

* 컨트롤러에서 모델한테 상태를 변경하라는 요청을 한다.

- 컨트롤러에서는 사용자의 행동을 받아 해석한다.

사용자가 버튼을 누른다든가 하는 어떤 행동을 하면 컨트롤러에서 그것이 무엇을 의미하는지 분석하고 그 행동에 따라서 모델을 어떤식으로 조잭해야 하는지 결정한다.

 

* 컨트롤러에서 뷰를 변경해 달라고 요청할 수 있다.

- 컨트롤러에서 뷰로부터 어떤 행동을 받았을 때, 그 행동의 결과로 뷰를 바꿔달라 할 수 있다.

예를 들어 컨트롤러에서 인터페이스에 있는 어떤 버튼이나 메뉴를 활성화 또는 비활성화 시킬 수 있다.

 

* 상태가 변경되면 모델에서 뷰한테 그 사실을 알린다.

- 사용자의 행동 때문이든 다른 내부적인 변화 때문이든 모델에서 무엇인가가 변경되면 모델에서 뷰한테 상태가 변경 되었음을 알린다.

 

* 뷰에서 모델한테 상태를 요청한다.

- 뷰에서 화면에 표시할 상태는 모델로부터 직접 가져온다.

예를 들어 모델에서 뷰한테 새로운 곡이 재생되기 시작했다고 알려주면 뷰에서는 모델한테 곡 제목을 요청하고 그것을 받아 화면에 표시한다.

컨트롤러에서 뷰를 바꾸라는 요청을 했을 때도 뷰에서 모델한테 상태를 알려달라고 요청할 수 있다.

 

예제

MVC 패턴을 공부하기 가장 좋은 방법은 MVC를 여러 개의 패턴이 함께 적용되어 완성된 하나의 디자인으로 보는 것이다.

모델에서는 자신의 상태를 알려야 하기 때문에 옵저버 패턴을 사용해서 상태가 바뀔 때 마다 뷰와 컨트롤러에게 연락한다.

컨트롤러는 뷰의 행동에 해당하기 때문에 스트래티지 패턴을 이용해서 다른 행동을 원할 시 다른 컨트롤러로 교환하기만 하면 된다.

뷰에서는 내부적으로 컴포지트 패턴을 써서 윈도우, 버튼 같은 다양한 구성요소를 관리한다.

 

 

뷰와 컨트롤러

뷰와 컨트롤러는 고전적인 스트래티지 패턴으로 구현되어 있다.

때문에 뷰 객체를 여러 전략을 써서 설정할 수 있으며 컨트롤러가 전략을 제공한다.

뷰에서는 애플리케이션의 겉모습에만 신경을 쓰고, 인터페이스의 행동에 대한 결정은 모두 컨트롤러에게 맡긴다.

스트래티지 패턴을 이용하므로 뷰를 모델로부터 분리시키는 데에는 도움이 된다.

 

뷰에 속하는 디스플레이는 여러 단계로 겹쳐져 있는 일련의 윈도우, 패널, 버튼, 텍스트, 레이블 등으로 구성된다.

각 디스플레이 항목은 복합 객체(윈도우 등) 또는 잎(버튼 등)이 될 수 있다.

컨트롤러에서 뷰한테 화면을 갱신해 달라고 요청하면 최상위 뷰 구성요소 한테만 갱신해 달라고 요청하면 된다.

나머지는 컴포지트 패턴에 의해 자동으로 처리 된다.

 

모델

모델에서는 옵저버 패턴을 써서 상태가 변경되었을 때 그 모델하고 연관된 객체들에게 연락을 한다.

옵저버 패턴을 이용해서 뷰 및 컨트롤러로부터 완전히 독립시킬 수 있다.

한 모델에서 서로 다른 뷰를 사용할 수 있고, 여러 개의 뷰를 동시에 사용하는 것도 가능하다.

 

MVC와 웹 환경

웹으 등장으로 여러 개발자들이 MVC를 브라우저/서버 모델에 맞게 변형시켜서 사용하기 시작했다.

“모델2(Model2)”방식을 가장 많이 쓰는데 서블릿과 JSP 기술을 사용하여 일반적인 GUI와 마찬가지로 모델, 뷰, 컨트롤러를 분리해서 디자인 할 수 있다.

 

 

1. 사용자가 HTTP요청을 하면 서블릿에서 그 요청을 수신한다.

- 사용자가 웹 브라우저를 이용해 HTTP요청을 한다.

보통 사용자 ID와 비밀번호 같은 폼 데이터가 함께 전달된다.

서블릿에서는 이런 폼 데이터를 받아 파싱한다.

 

2. 서블릿이 컨트롤러 역할을 한다.

- 서블릿은 컨트롤러 역할을 맡아서 사용자 요청을 처리하고, 대부분의 경우에 모델(보통 데이터베이스)에 어떤 요청을 하게 된다.

요청을 처리한 결과는 일반적으로 자바빈 형태르 포장된다.

 

3. 뷰는 JSP에 의해 표현된다. JSP에서는(4 자바빈을 통해 얻은) 모델의 뷰를 나타내는 페이지만 만들어 주면 된다.

 

4. 그 페이지를 만드는 과정에서 다음 단계의 작업을 위해 몇 가지 더 제어해야 할 일이 있을 수도 있다.

 

5. 뷰에서 HTTP를 통해서 브라우저 한테 페이지를 전달한다.

- 페이지가 브라우저한테 전달되면, 그 웹페이지가 사용자의 화면에 표시된다.

사용자가 또 다른 요청을 할 수 있으며, 새로운 요청도 지금까지의 과정과 같은 방식으로 처리한다.

모델2의 장점

제작 책임까지도 분리시켜주기 때문에 모델 2의 장점은 단순히 디자인적인 면에서 각 구성요소를 분리해주는 것에 그치지 않는다.

옛날에는 JSP에 접근할 수 있는 사람이라면 JAR에 대해서는 전혀 몰라도 누구든 자바 코드를 마음대로 만들 수 있었다.

하지만 대부분의 웹 제작자들은 컨텐츠와 HTML에 대해서는 잘 알지만 소프트웨어에 대해서는 그리 잘 알기 힘들다는 문제가 있었다.

 

모델 2가 등장하면서 개발자들은 서블릿에만 전념하면 되고, 웹 자작자들은 간단한 모델2 스타일의 JSP만 다루면 되는 환경이 조성되었다.

그래서 웹 자작자들은 HTML과 간단한 자바빈즈만 만지면 된다.


디자인 패턴과 모델2

모델2는 MVC를 웹에 맞게 적용시킨 것이다.

모델2는 교과서에 나오는 MVC하고 똑같이 생긴 것은 아니지만, 여전히 MVC의 핵심 요소들을 포함하고 있다.

단지 웹브라우저 모델의 특성을 반영하고 있을 뿐이다.

1. 옵저버 패턴

- 고전적인 의미에서 본다면 뷰는 더 이상 모델의 옵저버라고 할 수 없다.

모델한테 등록해서 모델의 상태가 바뀌었다는 연락을 받는다든가 하지 않기 때문이다.

하지만 여전히 모델의 상태가 바뀔 때 컨트롤러를 통해서 간접적으로 나마 연락을 반긴 한다.

게다가 컨트롤러에서는 뷰한테 빈을 건내주기 때문에 뷰에서 모델의 상태를 알아낼 수 있다.

 

- 브라우저 모델을 생각해 보면, 뷰에서는 브라우저로 HTTP응답을 할 때만 모델의 상태에 대한 정보가 필요하다.

HTTP응답을 하지않는 상황에서는 모델로부터 연락을 받아봤자 할 일이 없다.

페이지를 만들어서 브라우저로 보낼 때만 모델의 상태를 반영하여 뷰를 생성하는 것이 의미 있는 행동이 된다.

 

2. 스트래티지 패턴

- 컨트롤러 서블릿이 여전히 전략 객체로 쓰인다.

하지만 고전적인 MVC에서 처럼 뷰 객체에 컨트롤러 객체에 대한 래퍼런스가 들어가는 방식으로 구현되지 않는다.

그럼에도 불구하고 컨트롤러 서블릿이 뷰의 행동을 구현하는 객체라는 점과 다른 행동을 원하는 경우에 다른 컨트롤러로 바꿀 수 있다는 점에서 보면 여전히 스트래티지 패턴을 따른다고 불 수있다.

 

3. 컴포지트 패턴

- GUI와 마찬가지로 웹의 뷰도 결국은 중첩된 그래픽 구성요소로 이루어진다.

이 경우, HTML 코드를 통해 웹 브라우저에서 랜더링 된다는 차이점이 있긴 하지만, 그 밑엔 결국 복합 객체 형태의 객체 시스템이 있을 가능성이 매우 높다.

 

의문점

1. 컨트롤러에서 애플리케이션의 로직을 구현하는 경우가 있는지?

- 컨트롤러에서는 뷰를 위한 행동을 구현하기만 한다.

사용자가 뷰에 대해 취한 행동을 모델에 대한 요청으로 바꿔주는 것이 바로 컨트롤러의 역할이다.

모델에서는 그러한 요청을 받아서 필요한 작업을 처리하는 애플리케이션의 로직을 구현한다.

컨트롤러에서 모델의 어떤 메소드를 호출해야할지 결정하기 위해 분기문과 같이 어느 정도 간단한 작업을 처리할 수는 있지만, 그런 부분은 데이터를 관리하고 조작하기 위한 애플리케이션 로직이라고 할 수는 없다.

 

2. 푸시 방식을 사용해서 모델이 갱신 되었다는 연락을 할 때 모델의 상태도 같이 전달하면 되지 않나?

- JSP/HTML 뷰에서는 실제로 그런 방식을 사용하고 있다.

모델 자체를 빈으로 보내면 빈 속성을 사용해서 필요한 상태를 알아낸다.

하지만 옵저버 패턴에 대해 복습할 때 푸시 방식에 몇 가지 단점을 배웠었다.

옵저버의 재사용성, 불필요한 정보 전달 등의 단점이 있었다.

반응형
Comments