계층 나누기
소프트웨어를 Model, View, Presenter의 계층으로 분리합니다.
Model
로컬 데이터베이스 관리, 네트워크 통신을 통해 데이터와 관련된 작업을 처리합니다.
View
Android UI 작업을 처리합니다. UI 작업에는 화면을 그리거나, 애니메이션, 버튼 클릭, 스크롤, 스와이프 등 사용자 상호작용 이벤트를 받는 일이 있습니다.
Presenter
View와 Model의 중간에서 행동합니다.
Veiw에게 이벤트를 받아 처리합니다.
처리하기 위해서 필요한 데이터를 Model에게 요청합니다.
분리
일관된 요소끼리 계층을 나누어 응집도를 높이고, 각 계층의 변경이 댜른 계층에 영향이 미치지 않도록 합니다.
MVP는 프리젠테이션 계층을 View와 Presenter로 분리했습니다.
View에서는 Presenter의 명령을 받아 화면을 그리거나 사용자 상호작용 이벤트를 받아 Presenter에게 알려주기만 합니다. Presenter는 View의 이벤트를 받아 판단한후 필요한 데이터를 모델에게 요청해 처리합니다.
프리젠테이션 계층이란?
화면의 표시, 애니메이션, 사용자 입력 처리 등 UI에 관련된 모든 처리를 하는 계층입니다.
종속성
종속성이란?
클래스를 구현하기 위해 다른 클래스가 필요하다면 클래스는 다른 클래스에 종속되어있습니다.
종속성 규칙
모든 소스코드 종속성은 반드시 저수준이 고수준으로 향하게 해서 고수준은 저수준의 변경에 영향을 받지 않아야합니다.
종속성 규칙을 지킨다면 변경에 어려움이 줄어듭니다.
계층을 나눈 아키텍쳐가 동작하기 위해 종속성 규칙을 지켜야합니다.
고수준/저수준
추상화가 높거나, 비즈니스 로직, 외부에 영향 받지 않는 코드가 고수준이고, 구체적인 세부사항 코드는 저수준 입니다. 고수준은 적게 변경되고, 저수준은 입/출력과 가까우며 자주 변경됩니다.
일반적으로 클래스가 다른 클래스에 종속되어있다면 변경해야할 때 어려움이 커집니다.
MVP는 View와 Model이 Presenter를 통해 작업을 처리하기때문에 서로에 대한 종속성이 없습니다.
또한 View와 Presenter도 인터페이스를 이용해 서로의 종속성을 느슨하게 합니다.
계층 넘기
View와 Presenter는 서로의 경계를 넘어야합니다. Presenter가 View를 직접 호출하면 종속성 규칙을 위반하는 것입니다. 종속성 규칙을 지키면서도 해결하기 위해서 의존성 반전 원칙를 사용합니다.
의존성 반전 원칙
느슨하게 결합된 형태입니다. 고수준과 저수준은 둘 다 인터페이스에 의존합니다.
구현하기
Presenter와 View의 연결
Presenter와 View는 인터페이스를 이용해 의존성을 낮춥니다.
BasePresenter와 BaseView interface를 만듭니다.
interface BasePresenter { } interface BaseView<T> { var presenter: T }
interface BasePresenter {
}
interface BaseView<T> {
var presenter: T
}
Contract
하나의 Presenter는 하나의 View를 관리하는 1:1 관계를 가집니다.
1:1 관계를 가지는 Presenter와 View를 Contract 클래스에 명시합니다.
Presenter와 View에서 정의되는 추상 메서드도 포함합니다.
interface BasePresenter {
}
interface BaseView<T> {
var presenter: T
}
View, Presenter 구현
class HomeFragment : Fragment(), HomeContract.View {
override lateinit var presenter: HomeContract.Presenter
class HomePresenter(
private val HomeView: HomeContract.View
) : HomeContract.Presenter {
각 Viee와 Presenter는 서로를 Base interface로 가지고 있기 때문에 서로에 대한 의존성을 느슨하게 할 수 있습니다.
View, Presenter 주입
Activity에서 둘다 주입하거나, 주입을 시작합니다.
1. Activity에서 fragment(View)를 만들고 Presenter에 주입합니다.
interface HomeContract {
interface View: BaseView<Presenter> {
fun setTitle(title: String)
}
interface Presenter: BasePresenter {
fun onButtonClick()
}
}
2. Presenter에서 View에 Presenter를 주입합니다.
class HomePresenter(
val homeView: HomeContract.View
) : HomeContract.Presenter {
init {
homeView.presenter = this
}
의존성 주입
의존성 주입은 필요한 객체를 직접 만들어 사용하지 않고 다른 객체가 필요한 객체를 제공하는 것입니다. 객체의 생성과 사용을 분리합니다.
참고
http://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
https://github.com/android/architecture-samples/tree/todo-mvp-kotlin
https://www.geeksforgeeks.org/difference-between-mvc-mvp-and-mvvm-architecture-pattern-in-android/
https://ko.wikipedia.org/wiki/%EC%9D%98%EC%A1%B4%EC%84%B1_%EC%A3%BC%EC%9E%85
https://en.wikipedia.org/wiki/Dependency_inversion_principle
https://ichi.pro/ko/model-eul-boneun-keullin-akitegcheo-jeobgeun-bangsig-35325539213616
https://www.baeldung.com/mvc-vs-mvp-pattern
'Android' 카테고리의 다른 글
안드로이드 신입 과제 면접 회고 (0) | 2023.05.06 |
---|---|
[Glide] 이미지 로딩 시 자동으로 이루어지는 다운 샘플링 (0) | 2022.08.10 |
인텐트 필터 작성하고 테스트해보기 (0) | 2021.11.27 |
Android Task (0) | 2021.11.14 |
Activity의 생명주기, Life Cycle (0) | 2020.04.02 |