MVC 디자인 패턴

KangMinSoo·2021년 10월 20일
0

MVC패턴. 자세하게 공부해 놓으려고 정리한 글임.

MVC 패턴

image

정의:

모델 뷰 컨트롤러 (Model - View - Controller)는 소프트웨어 공학에서 웹 개발 시 사용되는 소프트웨어 *디자인 패턴.
보다 체계적인 틀 안에서 동적 웹을 개발할 수 있게 해준다.
MVC 패턴을 성공적으로 적용하여 개발하면 사용자 인터페이스로부터 비즈니스 로직을 분리하여
애플리케이션의 시각적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이 쉽게 고칠 수 있는 애플리케이션을 만들 수 있다.

*디자인 패턴

유지보수와 로직을 분리하고 코드를 재사용하는 등 개발에 있어서 좀 더 쉽고 편리하게 사용할 수 있게 만든 특정한 방법들을 디자인 패턴이라고 한다. 쉽게 말해 한 파일에 모든 로직이 들어있는 코드를 부분 별로 나누는 패턴을 나눈다고 생각하면 좋겠다.

종류에는 스트래티지 패턴, 옵저버 패턴, MVC패턴 등 여러가지가 있다.

MVC Pattern은 프로그래밍할 때 전체적인 아키텍쳐의 여러 디자인 패턴 중 하나이다.

도메인(비즈니스)로직과 UI로직을 분리하여 유지보수를 독립적으로 수행할 수 있게 하는 장점이 있다. 앞서 디자인 패턴을 하나의 덩어리 코드를 로직에 맞게 분리하는 패턴이라고 말했다. MVC패턴은 데이터(모델) 부분, UI(뷰-css, html)부분, 그리고 이 두가지를 컨트롤(컨트롤러)하는 부분 3가지로 나누는 패턴이라고 보면 쉽다.
image

MVC의 구조

사용자가 컨트롤러를 조작하면 컨트롤러는 모델을 통해서 데이터를 가져오고 그 정보를 바탕으로 시각적인 표현을 담당하는 뷰를 제어해서 사용자에게 전달한다. 이러한 MVC패턴의 구조를 보면
image
이러한 구조이다.

image
모델은 컨트롤러에, 컨트롤러는 뷰에, 뷰는 다시 유저에게, 유저는 다시 컨트롤러를 향해서 간다.

  • M (Model, domain) 모델

    애플리케이션의 정보, 데이터를 나타낸다. 데이터베이스, 처음의 정의하는 상수, 초기화 값, 변수 등을 뜻한다. 이러한 데이터, 정보들의 가공을 책임지는 컴포넌트이다.

개념적으로는,
M(Model)이란 프로그램이 작업하는 세계관의 요소들을 개념적으로 정의한 것이라고 볼 수 있다.
쉽게 말하면 , 오늘 저녁으로 김치찌개를 만들어 먹는다고 가정하자. 맛있는 김치찌개라는 목표를 정상적으로 수행하기 위해서 우선 레시피가 있어야 하고 적절한 재료와 식기 그리고 적절한 불의 세기 등이 필요하다.

이처럼 프로그램이 목표하는 작업을 달성하기 위한 물리적 개체, 규칙, 작업 등의 요소들을 구분되는 역할로써 정의해 놓은 것이 M(Model)이 된다.
Model은 *DTO와 DAO로 분류 할 수 있다.

결과적으로 Model을 잘 설계하는 것은 해당 도메인 세계를 얼마만큼 이해하고 있는지와도 밀접한 연관이 있다. 꼭 물리적인 요소뿐만 아니라 추상적인 요소 또한 해당 작업을 수행하는데 특정 책임과 역할로서 구분될 수 있다면 최대한 구체적이고 작은 entity를 유지하면서 Model을 설계하는 것이 중요하다.

모델(Model)의 규칙

  1. 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야 한다.
    화면안의 네모박스에 글자가 표현된다면, 네모박스의 화면 위치 정보, 네모박스의 크기 정보, 글자 내용, 글자의 위치 등등

  2. 뷰나 컨트롤러에 대해서 어떤 정보도 알지 말아야 한다.
    데이터 변경이 일어났을 때 모델에서 화면 UI를 직접 조정해서 수정할 수 있도록 뷰를 참조하는 내부 속성 값을 가지면 안된다는 말이다.

  3. 변경이 일어나면, 변경 통지에 대한 처리 방법을 구현해야만 한다.
    모델의 속성 중 텍스트 정보가 변경이 된다면, 이벤트를 발생시켜 누군가에게 전달해야 하며, 누군가 모델을 변경하도록 요청하는 이벤트를 보냈을 때 이를 수신할 수 있는 처리 방법을 구현해야 한다. 또한 모델은 재사용이 가능해야 하며 다른 인터페이스에서도 변하지 않아야 한다.

  • V(view) 뷰

    Input 텍스트, 체크박스 항목 등과 같은 사용자 UI요소를 나타낸다. 데이터 및 객체의 입력, 그리고 보여주는 출력을 담당한다. 데이터를 기반으로 사용자들이 볼 수 있는 화면.

입출력의 순서나 데이터 양식은 컨트롤러에 종속되어 결정되고, 도메인 모델의 상태를 변환하거나 받아서 렌더링 하는 역할을 한다.

뷰(view)의 규칙

  1. 모델이 가지고 있는 정보를 따로 저장해선 안된다.
    화면에 글자 등을 보여주기 위해 모델이가지고 있는 정보를 전달 받는다. 그 정보를 유지하기 위해서 임의의 뷰 내부에 저장하면 안된다. 단순히 네모 박스를 그리라는 명령을 받으면, 화면에 표시하기만 하고 그 화면을 그릴 때 필요한 정보들은 저장해선 안된다.

  2. 모델이나 컨트롤러와 같이 다른 구성요소들을 몰라야 한다.
    모델과 같은 자기 자신을 빼고는 다른 요소는 참조하거나 어떻게 동작하는지 알아서는 안된다. 그냥 뷰는 데이터를 받으면 화면에 표현만 해준다.

  3. 변경이 일어나면 변경통지에 대한 처리 방법을 구현해야만 한다.
    모델처럼 변경이 일어났을 시에 누군가에게 변경을 알려줘야 하는 방법을 구현해야 한다. 뷰에서는 화면에서 사용자가 화면에 표시된 내용을 변경하게 되면 이를 모델에게 전달해서 모델을 변경해야 할 것이다. 그 작업을 하기 위해 변경 통지를 구현한다. 그리고 재사용이 가능하게끔 설계를 해야 하며 다른 정보들을 표현할 때 쉽게 설계를 해야한다.

  • C (Controller) 컨트롤러

    controller는 model(데이터)과 view(UI)를 연결 시켜주는 다리 역할을 한다. 즉, 사용자가 데이터를 클릭하고 수정하는 것에 대한 이벤트들을 처리하는 부분을 뜻한다. 동시에 도메인 객체들의 조합을 위해 프로그램의 작동 순서나 방식을 제어한다. controller는 view와 model이 각각 어떤 역할과 책임이 있는 지 알고 있어야 한다.

컨트롤러(Controller)의 규칙

  1. 모델이나 뷰에 대해 알고있어야 한다.
    모델이나 뷰는 서로의 존재를 모르고 변경을 외부에 알리고 수신하는 방법만 가지고 있다. 이를 컨트롤러가 중재하기 위해 모델과 그에 관련된 뷰에 대해 알고있어야 한다.

  2. 모델이나 뷰의 변경을 모니터링 해야 한다.
    모델이나 뷰의 변경 통지를 받으면 이를 해석해서 각각의 구성 요소에게 통지를 해야 한다.
    또한 애플리케이션의 메인 로직은 컨트롤러가 담당하게 된다.

웹 프로그래밍에서는 controller에서 service layer를 분리하여 domain 로직이 수행되는 곳과 view의 요청을 매핑하는 곳을 독립적으로 관리할 수 있다.

MVC패턴을 사용하는 이유

사용자가 보는 페이지, 데이터처리 그리고 이 두 가지를 중간에서 제어하는 컨트롤러. 이 3가지로 구성되는 하나의 애플리케이션을 만들면 각각 맡은바에만 집중할 수 있게 되어 효율성을 높인다.

서로 분리되어 각자의 역할에 집중할 수 있게끔 개발을 하고 애플리케이션을 만든다면, 유지보수성과 애플리케이션의 확장성 그리고 유연성이 증가하고 코드를 재사용함으로써 중복 코딩이라는 문제점 또한 사라지게 된다.

MVC 패턴을 사용하는 프레임워크 , 라이브러리

image
image
image
구글의 Angular js, Python의 django, 자바의 Spring, facebook의 react(라이브러리)
어떤 목적에 따라 어떤 웹사이트를 만들지 원하는 목적에 따라 프레임워크를 사용해서 개발하면 된다.

*React는 MVC프레임워크는 아니고 VIew만 신경쓰는 라이브러리이다.
다른 웹 프레임워크와는 달리 Ajax, 데이터 모델링, 라우팅 같은 것이 없다.
그저 뷰만 신경쓴다. 다시 말해, UI 컴포넌트를 만드는 일만 하며 캡슐화를 잘 시켜줘서 재사용성이 높다.

MVC패턴 적용 시 고려해볼 만한 것들

1. TDD로 개발 할 수 있나?

-Model
MVC에서는 모델과 뷰를 완전히 분리하는 방식으로 작성할 것을 권장한다. 모델이 통신하는 컨트롤러와의 관계도 사실 자세히 살펴보면 모델이 컨트롤러를 호출하는 경우는 없다. 모델은 오로지 무언가의 호출에 응답할 뿐이고, MVC모델의 웹 애플리케이션에서는 컨트롤러가 모델을 호출하는 역할을 맡고 있을 뿐이다.
혹자는 이런 방식을 객체 지향 원칙 중 하나인 헐리우드 방식이라고 부르기도 한다. 모델은 웹 애플리케이션 구성 요소 중 TDD가 쉽게 적용되는 부분이고, 또 적용해야 하는 부분이다.

-View
뷰는 사용자의 동작과 연관되어 있는 부분이 많고 비교적 자주 변경되는 부분이다. 때문에 웹 애플리케이션 개발에서 많은 시간이 소요되는 영역이다. 따라서 뷰를 TDD로 개발하는 것은 효율이 낮을 뿐더러 쉽지 않다. 뷰는 다양한 요소들이 혼재되어 있다. 그럼에도 보통은 이를 분리해서 생각하지 않고 뷰라는 한 가지 개념으로만 접근하기 때문에 더욱 어렵게 느껴질 수 있다.

-Controller
컨트롤러에 대한 TDD 작성은 비교적 수월하다. MVC 모델에서 컨트롤러는 테스트하는 가장 간단한 방법을 소개하면 뷰로부터 넘어오는 요청(Request)를 가상으로 만들어주고, 그 결과에 해당하는 응답이 예상과 일치하는지 판단하면 된다.
모델 테스트보다는 귀찮고 복잡하지만 컨트롤러를 테스트 하는 것도 충분히 가능하고 프레임워크를 사용하면 manual로 하는 것보다 훨씬 수월하게 할 수 있다고 한다.

2.컨트롤러는 하나만 만들어야 하는가?

MVC의 뷰는 여러 개의 컨트롤러를 가지고 있다. 사용자는 컨트롤러를 사용하여 모델의 상태를 변경한다. 컨트롤러는 모델의 mutator함수를 호출하여 상태를 변경한다. 이때 모델의 상태가 변경되면 모델은 등록된 뷰에 자신의 상태가 변경되었다는 것을 알리고 뷰는 거기에 맞게 사용자에게 모델의 상태를 보여준다.

따라서 컨트롤러는 하나일 필요가 없다. 프로그램이 실행될 때 로직이 병렬적으로 분기된다면 컨트롤러를 여러개 두어도 상관없다. 오히려 더 깔끔한 설계가 될 수 있다.

각 컨트롤러는 Interface를 구현하는 방식으로 만들면, 유저 입력에 따라 if문으로 분기하여 컨트롤러를 실행하는 번거러움을 제거하고 다형성을 이용하여 유지보수 및 확장시에도 이점을 확보할 수 있다.

3. MVC의 한계점

한 모델은 다수의 뷰들을 가질 수 있다. 반대로 컨트롤러를 통해서 한 뷰에 연결되는 모델도 여러 개가 될 수 있다. 이는 결과적으로 뷰와 모델이 서로 의존성을 갖게 된다. 설계를 잘 한다면 모델 간의 의존성 뿐 아니라 뷰와 모델 사이에 생기는 의존성도 줄일 수 있다. 하지만 프로그램 특성상 필연적으로 화면에 복잡한 화면과 데이터 구성이 필요하다면 컨트롤러에 다수의 모델과 뷰가 복잡하게 연결되어 있는 상황이 발생할 수 있다.

-Massive View Contoller
MVC규모 자체가 너무 복잡하고 비대해져서 새 기능을 추가할때마다 의존성을 일일이 해결해야 하기 때문에 메소드 분석이나 테스트도 어렵게 된다. 이런 형태의 MVC를 Massive View Controller라고 부른다. 이는 MVC의 한계를 표현한 용어이기도 하다.
뷰와 모델을 중재하는 컨트롤러의 비중은 별로 크지 않을 것으로 생각할 수 있지만, 복잡한 화면을 구현하게 되면 Massive View Controller가 될 수 밖에 없다.

컨트롤러는 뷰와 라이프 사이클이 강하게 연결되어 있어서 분리하기 어렵고 유지 보수와 테스트가 힘들어진다.

4. MVC 패턴의 의의
MVC패턴은 결국 어떻게 분리할 것인가에 대한 해답 중 하나이다. 어떤 특정한 역할들에 대해 역할분담을 할 때 가이드라인을 제시하는 방법 중 하나가 바로 MVC패턴이라는 것이다. 이 패턴을 사용한 라이브러리나 프레임워크로 개발을 한다면 정말 쉽고 그리고 재밌는 경험을 느낄 수 있으며 아름다운 코드가 탄생하게 된다.

*참고
https://m.blog.naver.com/jhc9639/220967034588
https://velog.io/@ljinsk3/MVC-%ED%8C%A8%ED%84%B4
https://www.youtube.com/watch?v=AERY1ZGoYc8(얄코)
https://blog.gaerae.com/2016/04/hello-react.html

profile
주니어 개발자의 벨로그

0개의 댓글