Adapter, 누구냐 넌? — Data? View?

Android 에서 AdapterView(ListView, RecyclerView) 는 매우 중요한 위치를 가집니다.

반복적인 형태를 띈 많은 수의 View 를 효율적으로 관리하기 위해 재활용할 수 있는 View 로 바꾸고 화면에 필요한 View 만 표시할 수 있도록 함으로써 메모리와 동작에서 큰 효율을 가지고 있습니다.

그래서 반복적인 View 는 특정 Frame 으로 정의하고 Data 만 관리함으로써 개발자는 Frame 과 Data 만 정의하면 해당 화면을 매우 쉽게 구현할 수 있습니다.

일반적인 Adapter 의 모습

메신저등 데이터의 Add-Remove, 화면의 Refresh 가 빈번하더라도 배열에 추가/삭제 후 데이터의 변화를 알리기만 하면 알아서 화면이 갱신됩니다.

위의 코드를 보면 Adapter 는 Data 를 관리하고 RecyclerView 를 갱신하는 것을 알 수 있습니다.

하지만 이러한 간단한 구조가 Android Clean Architecture 와 맞물리면서 한가지 중요한 문제점을 가지게 되었습니다.

MVP 와 Adapter

Android 에서 가장 대중화된 Clean Architecture 인 MVP (Model-View-Presenter) 에서는 각각을 다음과 같이 정의하고 있습니다.

View : 실제 View 에 접근하고 화면을 갱신하는 역할을 수행.
Presenter : View 로부터 이벤트를 전달받고 View 에서 알 수 없는 Data 에 접근하고 로직을 수행하도록 Model 에 요청함.
Model : Data 에 직접 접근하고 관리함. Presenter 가 요청한 작업을 수행

MVP, MVC 등에서 Model 의 주역할은 데이터에 직접 접근하고 관리하고 외부의 요청을 수행하도록 합니다.

그럼 위의 샘플 코드를 MVP 로 전환해보도록 하겠습니다.

View(MainActivity) 에 Adapter 가 존재함으로써 Presenter 에서는 데이터를 완성하여 이를 다시 View 를 전달하여 화면을 갱신하도록 하고 있습니다.

Adapter 의 두 얼굴

MVP 의 논리대로라면 View 에는 실제 View 에 관련된 인스턴스로 구성되어야 합니다. 그렇다면 Adapter 는 View 일까요? 위의 코드에서는 Adapter 는 실제 List 를 가지고 있습니다. 이는 View 에 필요한 데이터를 가진 Model 에더 가깝다고 볼 수 있습니다.

Adapter 는 화면에 필요한 Item 을 구성하고 이를 통해 완성된 View 를 관리합니다. 그렇기 때문에 Adapter 는 View 와 Model 의 모습을 모두 가지고 있습니다.

Data? View?

이는 Android Framework 전체로 보면 AdapterView 로부터 Data 와 ItemView 를 분리함으로써 객체의 역할에 맞게 동작할 수 있도록 한 잘한 선택 중 하나라고 볼 수 있습니다. 하지만 Application 을 개발자 입장에서는 양쪽의 역할을 가지고 있습니다.

두개의 몸으로 나뉜 Adapter

Adapter 가 가지는 Data 와 View 를 Interface 를 이용하여 다시 분할하고 Presenter 에서는 DataModel 로 접근하고 View 에서는 DataView 로 접근하도록 하였습니다.

이제 View 에서는 직접 Adapter 에 접근하는 것이 아니라 AdpaterDataView 를 통해 ListView(RecyclerView) 를 갱신하며 데이터의 관리는 Presenter 가 AdapterDataModel 을 통해서 처리하도록 합니다.

결론

Adapter 는 ListView(RecyclerView) 에서 효율적으로 데이터와 뷰를 관리하기 위해 만들어진 것입니다. 하지만 그 과정에서 DataModel 과 View 의 역할을 동시에 수행하고 있기 때문에 Clean Architecture 에서는 그 역할을 명확하게 나누어서 설계기 모호한 부분이 있습니다.

따라서 Interface 를 이용하여 Adapter 가 가진 2개의 역할을 명확하게 나누도록 하였습니다. 그에 따라 Presenter 에서는 DataModel 만 접근하고 View 에서는 DataView 만 접근하도록 하였습니다.

객체 지향에서는 객체가 어떤 책임과 역할을 가지고 있느냐에 따라 객체를 분리하고 관리하도록 하고 있습니다. 그동안 MVP 가 지향하는 각각의 역할과 충돌이 있었던 Adapter 에 대해 명확한 역할을 가지도록 하였습니다.

여태까지의 내용은 다음의 Github 저장소에 참조할 수 있는 소스를 공개하였습니다.

https://github.com/ZeroBrain/Android-MVP-AdapterRoleSample

Show your support

Clapping shows how much you appreciated SeongUg Steve Jung’s story.