Model + View + Controller 형태를 가지는 디자인 패턴이다.
MVC(Model-View-Controller)패턴은 웹 애플리케이션에서 가장 많이 쓰이는 디자인 패턴 중 하나이다.
레이어 분리를 지향하는 패턴인데, 애플리케이션을 확장하고, 테스트하고 유지하는데 필요한 노력의 크기를 줄여준다.
사용자가 컨트롤러를 통해 모델을 변화시키면 뷰가 업데이트된다. 비즈니스 로직의 경우 모델이 있어야 하지만, 컨트롤러 또는 뷰에 있을 수도 있다.
- Model : 비즈니스 로직을 나타내고 클래스의 집합이다. 데이터가 바뀌고 어떻게 조작되는지에 대한 비즈니스 규칙을 디자인하는데 동작한다.
비즈니스 로직을 처리한 후 컨트롤러와 뷰에 전달한다.
데이터베이스와 소통을 한다.- View : UI(User Interface) 컴포넌트를 나타낸다. 뷰는 컨트롤러가 폼 형태로 되돌려준 결과를 보여준다. 모델에게서 전달받은 데이터를 저장하면 안된다.
즉, 유저가 보는 화면부분을 말한다.- Controller : 모델과 뷰 사이를 이어주는 브릿지 역할. 들어오는 요청을 처리하는 부분이다.
뷰에서의 action과 event에 대한 input 값을 받는다. 모델에서 받은 데이터를 가공할 수 있다.모델에서 뷰로가는 과정을 통해 컨트롤러는 사용자의 데이터를 가져온다.
동작 순서
1. Client의 Request가 Controller에 들어오게 된다.
2. Controller는 Request를 확인하고, Model을 업데이트한다.
3. Controller는 Model을 나타내줄 View를 선택한다.
4. View는 Model을 이용하여 화면에 나타낸다.
그래서 MVC 패턴을 왜 사용하는가?
유지 보수의 편리성 때문 !!(컴포넌트별로 관리가 가능하다!)
- 또, 시스템 결합도를 낮추어주기때문에, 비즈니스 요건 변경등으로 인한 코드 변경 시에도 오류나 버그의 발생을 줄여준다.
- MVC 패턴은 Spring Framework와 JSP(Java Servlet Page)를 사용한 웹 애플리케이션 개발에 가장 많이 사용하는 패턴이다.
cf)나는 파이썬의 MTV 디자인 패턴을 사용하였는데, Model은 같은 의미이고 T는 MVC의 View역할, MTV의 View는 MVC의 Controller역할을 하는 패턴!!장점
- 개발 속도를 병렬적으로 가속화 시킬 수 있다.
- 여러 개의 뷰를 모델에 빌드할 수 있다. 비즈니스 로직과 데이터가 분리되어 있기 때문에 코드 복제가 제한된다.
- 변경사항이 전체 모델에 영향을 주지 않는다.
- 데이터를 어떠한 형태의 가공 없이 반환한다.
- 디버깅이나 코드 가독성이 좋아진다.
단점- View와 Model 사이의 의존성이 높다. 즉, 높은 의존성은 애플리케이션이 커질수록 복잡해지고 유지보수가 어려워 질 수 있다.
한계점
뷰와 모델이 컨트롤러에 의해 제어되기때문에 복잡한 대규모의 프로그램의 경우 컨트롤러가 불필요하게 커지는 현상이 발생한다. 이러한 현상을 Massive-View-Controller라고 한다.
이러한 문제를 해결하기 위해 나온 패턴이 MVP, MVVM, Flux, Redux, RxMVVM 패턴이 있다.
- 비즈니스 로직?
비즈니스 로직(Business logic)은 컴퓨터 프로그램에서 실세계의 규칙에 따라 데이터를 생성, 표시, 저장, 변경하는 부분을 말한다. 즉, 보이는 것의 뒤에서 일어나는 각종 처리를 말한다.
- <예시>
회원가입
유효성 검증을 예로들면 유효성 검사 후 아이디 또는 비밀번호 값을 사용해도 되는지에 대해서 시각적으로 표시해주는 것을 프레젠테이션, 뷰 영역이라고 한다.
중복검사를 위해 데이터 베이스를 조사하게 되는 일련의 과정을 로직 또는 모델 영역이라고 하는데, 즉, 유저의 눈에는 보이지 않지만, 유저가 바라는 결과물을 올바르게 도출할 수 있게 짜여진 코드 로직이 비즈니스 로직이 된다.
Model + View + Presenter의 형태(MVC의 구조를 보완하기위해 나온 디자인 패턴인데, MVC의 Controller의 역할을 MVP의 Presenter가 한다고 생각하면 된다.)
MVP(Model-View-Presenter)패턴 에서는 페이지 조절과 전시가 View에 의해 이루어진다.
Presenter는 사용자로부터 받는 모든 입력값을 수집하며 이것들을 모델에 즉각적으로 보내고, 결과를 뷰로 전달한다.
Controller의 기능을 Presenter가 대신하게 되는데, 뷰의 인터페이스 또한 포함한다.
- Model : MVC와 비슷하게 모델은 비즈니스 로직을 나타내고 클래스의 집합으로 특징된다. 이 부분은 데이터가 바뀌고 조작되는지에 대한 비즈니스 규칙을 디자인하는데 동작한다.
- View : 마찬가지로 MVC와 비슷하게 뷰는 UI 컴포넌트를 나타낸다. 뷰는 컨트롤러가 폼 형태로 되돌려준 결과를 보여준다. 모델은 또한 UI에 뷰로 변환될 수 있다.
- Presenter : 뷰를 대신하여 모든 UI 이벤트를 알려주기 위해, 프레젠터는 온전한 책임을 진다. 뷰는 사용자로부터 입력을 제공하고 데이터는 모델의 도움으로 필터되며, 결과는 뷰로 전달된다. View에서 요청한 정보로 Model을 가공 후 View에 전달해 준다.
동작 순서
1. 사용자의 Request가 View를 통해 들어온다.
2. View는 데이터를 Presenter에 요청한다.
3. Presenter는 Model에게 데이터를 요청한다.
4. Model은 Presenter에서 요청받은 데이터를 반환한다.
5. Presenter은 반환 받은 데이터를 View에 응답한다.
6. View는 응답받은 데이터를 화면을 통해 나타낸다.
왜 사용하는가???
MVC모델을 보완한게 MVP라고 하는데 왜 사용하나면, MVC같은 경우는 Model과 View의 의존성때문에 복잡하고 규모의 프로젝트가 되었을 때 문제가 발생한다. 그래서 그 의존관계를 없애고 오직! Presenter에 의해서 상태나 변화를 얻을 수 있는 MVP 패턴을 사용하게 되는 것이다.
장점
- 애플리케이션의 디버깅을 더 쉽게 만든다.
- 코드의 재사용성을 증가시킨다. 뷰의 컨트롤을 위한 여러 개의 프레젠터를 가질 수 있다.
- 비즈니스 로직과 영속성 로직을 Activity와 Fragment 클래스에서 분리할 수 있다.
- View와 Model의 의존성이 없다.
단점- View와 Model의 의존성이 줄어들었지만, View와 Presenter의 의존성이 높아졌다. 애플리케이션이 복잡해질수록 Presenter가 복잡해지는 문제가 있다.
Model + View + View Model 의 형태
비즈니스 로직과 프레젠테이션 로직을 분리하여 유지 및 보수가 용이해진 디자인 패턴이다.
MVC패턴의 Activity와 Fragment에 코드를 전부 때려넣는 방식이었는데, 앱의 규모가 커지면서 클래스 하나에 방대한 코드가 쌓여 가독성이 떨어지는 문제가 발생하게 되는데 (이러한 코드를 스파게티 코드라고 함) 이를 해결하기 위해서 나온 디자인 패턴이다.
- View
다른 MVC,MVP 모델과 같이 UI(User Interface)에 대한 부분을 다루는 컴포넌트이다. 사용자가 스크린을 통해서 보는 것들에 대한 구조, 레이아웃, 형태를 정의한다.
Animation같은 UI 로직을 포함하되, 비즈니스 로직을 포함하면 안된다.
ViewModel의 데이터 변화를 관찰(Observing)해 UI를 갱신한다.
View는 DB에 직접 접근하는 것이 아니라, UI 업데이트에만 전념하는데, View Model을 Observing하고 있기에 데이터 변화에 더욱 능동적이다.
Livedata(Observing 패턴)을 이용하는데, View Model안에 있는 LiveData 객체를 DataBinding을 통해 UI단에서 관찰하고, 자동으로 UI를 갱신한다.(데이터의 불일치성을 줄여줌)
LiveData
View가 ViewModel을 관찰할 때, 그 관찰 대상이 되는 관찰 가능한(Observable) 데이터 홀더 클래스이다. View에서 ViewModel의 LiveData를 관찰하게 되면 데이터가 변경될 때 내부적으로 자동으로 알려주게 된다. Live Data는 Activity 및 Fragment의 생명주기를 인지한다. 즉, Activity가 화면 위에 활성화되어 있을 때만 UI변경 등의 기능을 동작하게 되고, Destroy되 상태에서는 동작하지 않기 때문에 메모리 릭의 발생을 줄여준다.
Repository
ViewModel과 데이터를 주고받기 위해, 데이터 API를 포함하는 클래스다. 앱에 필요한 데이터, 즉 내장 데이터베이스나 외부 웹 서버 등에서 데이터를 가져온다. 따라서 ViewModel은 DB나 서버에 직접 접근하지 않고, Repository에 접근하는 것으로 앱의 데이터를 관리한다. Repository의 존재 덕분에 ViewModel은 데이터를 관리할 필요가 없게 된다.
RoomDatabase
SQLite 데이터베이스를 편하게 사용할 수 있도록 해주는 라이브러리이다. SQLite의 코드를 직접 작성하는 경우, 직접 테이블을 Create하거나 쿼리문을 일일이 변수를 통해 작성해주어야 했지만, Room을 쓰면 조금 더 직관적이고 편리하게 DB를 사용할 수 있다.
- ViewModel
View가 사용할 Method와 Field를 구현하고, View에게 상태변화를 알리는 역할.
View가 데이터를 요청하고 ViewModel은 Model로부터 요청한 데이터를 받는다.
View Model과 Model은 1:N 관계이다. View가 데이터를 쉽게 사용할 수 있도록, 모델의 데이터를 가공한다. 데이터의 가공 로직은 View Model에서 해야지, View에 들어가서는 안된다.
프레젠테이션 로직을 포함한다.
즉 !, A,B의 데이터를 View Model에서 가공하여 C를 만들어서 View에서는 C만을 이용해서 화면에 뿌려야하는데, A,B데이터를 View단에서 가공하여 화면에 뿌리면 안된다는 것!- 앱 회전이나 언어 변경등의 앱 종료(Destroy)에도 사라지지 않는 UI를 위한 데이터를 가지고 있다. AsyncTask는 액티비티나 프래그먼트의 생명주기에서 자유로울 수 없지만, ViewModel은 View와 분리되어 있기 때문에 액티비티가 Destroy 되었다가 다시 Create 되어도 종료되지 않고 데이터를 여전히 가지고 있다.
- Model
비즈니스 로직과 유효성 검사와 데이터를 포함하는 앱의 도메인 모델이다.즉, 앱에서 사용할 데이터에 관련된 행위와 데이터를 다룬다.
DB 사용, Retrofit을 통한 백엔드 API호출(Repository, Database 부분)
- Retrofit : retrofit 은 안드로이드 애플리케이션에서 통신(networking) 기능에 사용하는 코드를 사용하기 쉽게 만들어놓은 라이브러리이다. REST 기반의 웹 서비스를 통해 JSON 구조의 데이터를 쉽게 가져오고 업로드할 수 있다.
왜 MVVM 패턴을 사용해야 하는가???
요구 사항 변경, 기획 변경, 디자인 변경, 치명적 버그 출현 등으로 코드의 변경이 필요할 때가 있는데, 의존성이 낮기때문에 변경에대해 덜 영향력이 있는 MVVM 패턴으로 개발을 하면 코드의 변경을 최소화 할 수 있다.
비즈니스 로직과 프레젠테이션 로직을 UI로부터 깔끔하게 분리할 수 있다.
유지 및 보수가 정말 좋다.
장점
- 뷰 모델은 모델과 뷰 사이의 어댑터역할로, 변경이 발생하였을 때 변경을 최소화할 수 있다.
- 모델과 뷰 모델이 뷰로부터 독립적!(뷰 모델과 모델을 독립적으로 개발 가능, 테스트의 용이성)
- 개발 기간 동안 개발자와 디자이너가 동시에 독립적(병렬적) 작업이 가능
- UI 디자인이 나오지 않더라도 뷰와 뷰 모델을 먼저 개발가능
단점
- 거대하고 복잡한 앱을 위해 고안된 패턴이기에 소형 앱에서 사용하게 되면 오버헤드가 커진다.
- 오버헤드 ? 는 프로그램의 실행흐름에서 나타나는 현상중 하나
예를 들어 , 프로그램의 실행흐름 도중에 동떨어진 위치의 코드를 실행시켜야 할 때 , 추가적으로 시간,메모리,자원이 사용되는 현상
즉, 특정 기능을 수행하는데 소모되는 간접적인 시간, 메모리 등 자원을 말한다.
예를들어, 10초 걸리는 기능이 간접적 원인으로 1분이 소모되면, 오버헤드는 50초가 되는것 !- 앱이 너무 거대해지면 앱의 메모리 소모가 데이터 바인딩에 의해서 커진다.
- 구조가 복잡하다는 단점이 있다. 그래서 Android Architecture Components(AAC)라는 것을 구글에서 지원하는 라이브러리 모음이다. 테스트와 유지 관리가 쉬운 앱을 디자인할 수 있도록 도와주는데, 수명주기를 관리하고, 메모리 누수 방지, UI에 데이터 로드를 쉽게 한다.
🐾
이렇게 다양한 디자인 패턴이 있다는 것과 계속 디자인 패턴은 앞의 단점들을 보완해서 새로 만들어지고 있는 부분들을 알게 되었다. 특히, Model과 View 그리고 Controller의 역할을 하는 부분들의 책임과 역할에 대해서 조금 더 논리적이고 구체적인 이해가 있다면, 디자인 패턴을 활용하여 개발을 할 때 조금 더 깔끔하고 논리적인 코드를 작성할 수 있을 것이다 라고 생각이 들었다.
프로그래밍 공부를 해보면, 용어도 어렵고 해야할 공부가 정말 많다. 하지만, 하나하나 조각을 맞추다보면 큰 퍼즐을 이해하는 순간들이 오는 것 같다. 그래서 이 공부가 더욱 매력적인게 아닌가하는 생각을 한다.