Android

Android 06. Platform Architecture(플랫폼 아키텍처)

shin96bc 2022. 5. 30. 13:53

출처: https://developer.android.com/guide/platform?hl=ko

(1) 아키텍처 구조

     1) Linux Kernel(리눅스 커널)

          <1> Android 플랫폼의 기반은 Linux 커널 입니다. 예를들어 ART(Android 런타임)는 스레딩 및

                 하위 수준의 메모리 관리와 같은 기본 기능에 Linux 커널을 사용합니다.

     

          <2> Linux 커널을 사용하면 Android가 주요 보안 기능을 활용하고 기기 제조업체가 널리 알려진

                 커널용 하드웨어 드라이버를 개발할 수 있습니다.

 

     2) Hardware Abstraction Layer(하드웨어 앱스트랙션 레이어: 하드웨어 추상화 계층)

          <1>  HAL( Hardware Abstraction Layer )은 상위 수준의 Java API 프레임워크에 기기 하드웨어

                  기능을 노출하는 표준 인터페이스를 제공합니다. HAL 은 여러 라이브러리 모듈로 구성되어

                  있으며, 카메라 또는 블루투스 모듈과 같은 특정 유형의 하드웨어 구성 요소를 위한

                  인터페이스를 구현합니다. 

     

          <2> 프레임워크 API 가 기기 하드웨어에 액세스하기 위해 호출을 수행하면 Android System 이

                 해당 하드웨어 구성요소에 대한 라이브러리 모듈을 로드합니다.

 

     3) Android Runtime(안드로이드 런타임)

          <1> Android 버전 5.0( API Level 21 ) 이상을 실행하는 기기의 경우, 각 앱이 자체 프로세스 내에서

                자체 ART 인스턴스로 실행됩니다. ART는 DEX 파일을 실행하여 저용량 메모리 기기에서

                여러 가상 머신을 실행하도록 작성되었습니다. DEX 파일은 Android 용으로 특별히 설계된

                바이트코드 형식으로, 최소 메모리 공간에 맞게 최적화되어 있습니다. Jack과 같은 툴체인을

                빌드하고, Java 소스를 Android 플랫폼에서 실행될 수 있는 DEX 바이트코드로 컴파일 합니다.

 

          <2> ART( Android Runtime )  의 주요 가능

                1> AOT( Ahead Of Time ) 및 JIT( Juse In Time ) 를 컴파일 해줍니다.

                2> 최적화된 가비지 컬렉션( GC )이 있습니다.

                3> Android 9( API Level 28 ) 이상에서 앱 패키지의 DEX( Dalvik Executable ) 형식 파일이 더욱

                     간소한 기계 코드로 변환되었습니다.

                4> 전용 샘플링 프로파일러, 상세 진단 예외 및 크래시 보고, watchpoint 를 설정하여 특정

                     필드를 모니터링 할 수 있는 기능을 비롯한 향상된 디버깅 지원 기능이 있습니다.

 

          <3> Android 버전 5.0( API Level 21 ) 이전 버전에서는 Dalvik 이 Android Runtime 이었습니다.

                 앱이 ART 에서 제대로 실행되면, Dalvik에서도 잘 실행되지만, Dalvik 에서 실행되는 앱이

                 ART 에서도 잘 실행된다는 보장은 없습니다.

          

          <4> Android 에는 Java API 프레임워크가 사용하는 몇가지 Java 8 언어 기능을 포함하여 대부분의 

                 Java 프로그래밍 언어 기능을 제공하는 일련의 핵심 런타임 라이브러리도 포함되어 있습니다.

 

     4) Native C / C++Libraries(네이티브 C / C++ 라이브러리)

          <1> ART 및 HAL 등의 많은 핵심 Android 시스템 구성 요소와 서비스가 C 및 C++ 로 작성된 네이티브 

                 라이브러리를 필요로 하는 네이티브 코드를 기반으로 빌드되었습니다. Android 플랫폼은 

                 Java 프레임워크 API 를 제공하여 이러한 일부 네이티브 라이브러리의 기능을 앱에 노출합니다.

                 예를 들어, Android 프레임워크의 Java OpenGL API 를 통해 OpenGL ES 에 엑세스하여 앱에서

                 2D 및 3D 그래픽을 그리고 조작할 수 있는 지원 기능을 추가할 수 있습니다.

 

          <2> C 또는 C++ 코드가 필요한 앱을 개발하는 경우에는 Android NDK 를 사용하여 네이티브

                 코드에서 직접 이러한 몇몇 네이티브 플랫폼 라이브러리에 엑세스할 수 있습니다.

 

     5) Java API Framework

          <1> Android OS 의 전체 기능 세트는 Java 언어로 작성된 API 를 통해 액세스할 수 있습니다.

                 이러한 API 는 핵심 모듈식 시스템 구성 요소 및 서비스 재활용을 단순화하여 Android 앱을 제작

                 하는 데 필요한 빌딩 블록을 구성하며, 이러한 빌딩 블록에는 다음이 포함됩니다.

               1> 기능이 풍부하며 확장 가능한 뷰 시스템

                     1. 목록, 그리드, 텍스트 상자, 버튼 및 삽입 가능한 웹브라우저를 포함하여 앱의 UI 를

                           빌드하는 데 사용합니다.

               2> Resource Manager 

                     1. 현지화된 문자열, 그래픽 및 레이아웃 파일과 같은 코드가 아닌 리소스에 대한 액세스를

                         제공합니다.

               3> Notification Manager

                     1. 모든 앱이 상태 표시줄에 사용자 지정 알림을 표시할 수 있도록 지원합니다.

               4> Activity Manager

                     1. 앱의 수명 주기를 관리하고 공통 탐색 백 스택을 제공합니다.

               5> 콘텐츠 제공자

                     1. 앱이 주소록 앱과 같은 다른 앱의 데이터에 액세스하거나 자신의 데이터를 공유할 수

                          있도록 지원합니다.

          <2> 개발자는 Android 시스템 앱이 사용하는 것과 동일한 프레임워크 API 에 대한 전체 액세스 

                 권한을 가집니다.

 

     6) System Apps

          <1> Android 는 이메일, SMS 메시징, 캘린더, 인터넷 검색, 주소록 등의 주요 앱 세트와 함께

                제공됩니다. 플랫폼에 기본적으로 포함된 앱에는 사용자가 설치하도록 선택하는 앱과 구별되는

                특별한 상태가 없습니다. 따라서 타사 앱이 사용자의 기본 웹 브라우저, SMS 메시징 또는 기본

                키보드가 될 수 있습니다.(단, 시스템의 설정 앱 등 몇가지 예외가 적용될 수 있습니다.)

 

          <2> 시스템 앱은 사용자를 위한 앱으로도 작동하고 개발자가 자신의 앱에서 액세스할 수 있는 주요 

                 기능을 제공하기 위한 용도로도 작동합니다. 예를 들어, 앱이 SMS 메시지를 제공하고자 할 경우

                 해당 기능을 직접 빌드할 필요가 없습니다. 그 대신, 이미 설치된 SMS 앱을 호출하여 지정한 

                 받는 사람에게 메시지를 제공할 수 있습니다.

 

(2) 일반적인 아키텍처 원칙

     1) 관심사 분리

          <1> Activity 나 Fragment 에 모든 코드를 작성하는 실수는 흔합니다. UI 기반 클래스는 

                 UI 및 OS 상호작용 등의 로직만 포함해야 합니다.

          <2> 이러한 클래스를 최대한 가볍게 유지하면 생명주기( Life Cycle ) 관련 문제들을 피할 수 있습니다.

          <3> Activity 및 Fragment 구현은 소유의 대상이 아니며 Android OS 와 App 사이의 계약을 나타내는

                  클래스일 뿐입니다.

          <4> 언제든지 OS 가 클래스를 제거할 수 있으니 이러한 클래스에 대한 의존성을 최소화 하는 것이 

                  좋습니다.

 

     2) Model 에서 UI 구동

          <1> 또 하나의 중요한 원칙은 Model 에서 UI 를 구동해야 한다는 것입니다.

                  가급적 지속성 있는 Model 을 권장합니다.

          <2> Model 은 앱의 데이터 처리를 담당하며, 앱의 View 객체 및 App 구성요소로부터 독립되어

                 있습니다. 그래서 앱의 생명주기 관련 문제의 영향을 받지 않습니다. 지속성 있는 Model이

                 이상적인 이유입니다.

               1> Android OS 에서 리소스를 확보하기 위해 앱을 제거해도 사용자 데이터는 삭제되지 않습니다.

               2> 네트워크 연결이 취약하거나 연결되어 있지 않아도 앱이 계속 작동합니다.

          <3> 데이터 관리 책임이 잘 정의된 Model 클래스를 기반으로 앱을 만들면 쉽게 테스트하고 일관성을 

                   유지할 수 있습니다.

 

(3) 권장하는 앱 아키텍처

     1)  ACC( Android Architecture Components ) 

          <1> ACC 란 테스트와 유지보수가 쉬운 앱을 디자인할 수 있도록 돕는 라이브러리의  모음입니다.

출처:&nbsp;https://nobase-dev.tistory.com/281

          <2> 위의 다이어그램은 앱을 설계한 후 모듈들이 어떻게 상호작용해야 하는지를 보여줍니다.

          <3> 각 구성요소가 한 수준 아래의 구성요소에만 종속됨을 볼 수 있습니다.

                  Activity 및 Fragment 는 ViewModel 에만 종속됩니다.

          <4> Repository 는 여러 개의 다른 클래스에 종속되는 유일한 클래스 입니다.

                  Repository 는 지속성 있는 데이터 모델과 원격 백엔드 데이터 소스에 종속됩니다.

                  이 설계는 일관되고 쾌적한 사용자 환경을 제공합니다.

          <5> 사용자가 앱을 닫은 후 재사용시 앱이 로컬에 보존하는 사용자 정보가 바로 표시됩니다.

                  이 데이터가 오래된 경우 앱의 Repository 모듈이 Background 에서 데이터 업데이트를

                  시작합니다.

 

     2) UI 빌드

          <1> UI 에 필요한 데이터는 ViewModel 아키텍처 구성요소에 기반한 ViewModel 에서 정보를 

                 유지합니다.

          <2> ViewModel 객체는 UI 구성요소에 관한 데이터를 제공하고 모델과 커뮤니케이션하기 위한

                 데이터 처리 비즈니스 로직을 포함합니다. ViewModel 은 UI 구성요소에 관해 알지 못하므로

                 구성 변경(세로 -> 가로모드)의 영향을 받지 않습니다.

          <3> ViewModel 에서는 데이터 객체에 대한 변경 등을 View 에 알려야 합니다. 여기에서 

                  LiveData 가 사용됩니다.

          <4> LiveData 는 객체 변경사항을 모니터링 할 수 있으며, Activity / Fragment / Service 와 같은

                 앱 구성요소의 생명주기 상태를 고려한 로직을 포함합니다.( LiveData 필드는 생명주기로

                 인해 더 이상 필요하지 않은 참조를 자동으로 정리합니다. ) 

          <5> Activity 나 Fragment 에서 LiveData 객체를 observe 후 변경시에 대한 콜백 onChange() 를

                 사용해 UI 를 새로고침할 수 있습니다.

          <6> LiveData 는 생명주기를 인식하기 때문에 Activity 나 Fragment 의 onStop(), onDestroy()

                 메서드 등에 대한 처리를 하지 않아도 됩니다.

 

     3) Data 가져오기

          <1> 데이터를 가져오는 방식은 내부 데이터나 외부 API 를 통해 데이터를

                  가져오는 방식들이 있습니다.

          <2>  ViewModel 에서 직접 해당 라이브러리를 이용하여 데이터를 LiveData 객체에 할당하는

                  방법이 있습니다. 이 경우 ViewModel 클래스에 너무 많은 책임이 부여되어 관심사 분리

                  원칙을 위반하게 됩니다. 또한 ViewModel 의 범위는 Activity 나 Fragment 생명주기에

                  연결되어 있으므로 데이터가 손실될 수도 있습니다.

                  그래서 Repository 모듈을 사용하여 데이터 작업을 처리합니다.

          <3> Repository 는 지속적인 모델, 웹 서비스, 캐시 등 다양한 데이터 소스 간 중재자로

                 볼 수 있습니다. 즉, 관심사 분리로 인해 데이터 가져오는 방법을 알지 못하는

                 ViewModel 에게 데이터를 가져와서 넘겨주는게 Repository 의 역할 입니다.

 

     4) 구성요소 간 종속성 관리

          <1> Repository 클래스에서 WebService 를 통해 데이터를 가져올 경우 WebService 클래스의

                 종속성을 알아야 합니다. 이러한 상황에서 다른 클래스에서도 WebService 가 필요한 경우

                 코드를 복제해야 합니다. 

          <2> 이런 문제를 해결하기 위한 설계 패턴

               1> 종속성 주입( DI: Dependency Injection )

                    1. 클래스가 자신의 종속성을 구성할 필요 없이 종속성을 정의할 수 있습니다.

               2> 서비스 로케이터( Service Locator )

                    1. 클래스가 자신의 종속성을 구성하는 대신 종속성을 가져올 수 있는 레지스트리를 

                        제공합니다.

               3> 이러한 패턴을 사용하면 테스트 및 프로덕션 데이터 가져오기 구현 등을 신속하게

                     전환할 수 있습니다.

 

     5) ViewModel 과 Repository 연결

          <1> 만약 DI 를 사용하여 Repository 를 주입했다고 한다면, Repository 가 WebService

                     객체를 호출을 하지만 하나의 데이터 소스에만 의존하게 되어서 유연성이 

                     떨어지게 됩니다.

           <2> 이러한 문제를 해결하기 위해 Repository에 데이터를 캐시하는 소스를 추가하면 좋습니다.

 

     6) 지속되는 데이터

          <1> 위처럼 Repository 에 캐시하는 소스를 추가하면 앱을 나갔다가 들어오거나 하는 경우에

                  Repository 가 메모리 내 캐시에서 데이터를 가져옵니다. 하지만 장시간 프로세스를 종료 후

                  들어온다면 다시 네트워크에서 데이터를 가져와야 합니다. 이런 경우에는 Room 같은 

                  라이브러리가 필요합니다.

          <2> Room 이란 스마트폰 내장 DB에 데이터를 저장하기 위해 사용하는 라이브러리 입니다.

          <3> Room 에서는 Annotation 으로 로컬 스키마 정의가 가능합니다.( @Entity, @PrimaryKey )

                 RoomDatabase 를 구현하여 추상 클래스를 만들면 Room 에서는 자동으로 구현을 

                 제공합니다. 그리고 데이터를 데이터베이스에 액세스하기 위해 데이터 액세스 객체( DAO ) 를

                 만듭니다. Room 메서드에서 LiveData 를 사용하면 데이터 변경시 자동으로 모든

                 Observer들 에게 알리게 됩니다. DAO 를 정의했으면 데이터베이스 클래스에서 DAO 를

                 참조 후 Repository 의 소스를 수정하면 됩니다.

 

     7) 권장사항 정리

          <1> Activity, Service, Broadcast, Receiver 와 같은 앱의 진입점을 데이터 소스로 지정하지

                 않습니다.

          <2> 앱의 다양한 모듈 간 책임이 잘 정의된 경계를 만듭니다.

          <3> 각 모듈에서 가능하면 적게 노출합니다.

          <4> 각 모듈을 독립적으로 테스트하는 방법을 고려합니다.

          <5> 다른 앱과 차별되도록 앱의 고유한 핵심에 초점을 맞춥니다.

          <6> 가능한 한 관련성이 높은 최신 데이터를 보존합니다.

          <7> 하나의 데이터 소스를 단일 소스 저장소로 지정합니다.

         

(4) Android Design Pattern(안드로이드 디자인 패턴)

     1) 디자인 패턴이란 무엇인가?

출처: 위키피디아

          <1> 프로그래밍할 때 다양한 문제 상황에 대한 재사용 가능한 해결책 입니다.

                 (일반적인 문제를 해결하기 위해 최선의 방법을 공식화 혹은 정의 하는 것)

          <2> 패러다임과 알고리즘과는 다릅니다.

                  (객체지향 패러다임이든 함수형 프로그래밍 패러다임이든 문제상황은 일관되기에

                   패러다임과 디자인 패턴은 동의어가 될 수 없습니다. 알고리즘도 마찬가지로 문제상황은

                   일관되기 때문에 알고리즘과도 동의어가 될 수 없습니다. 디자인 패턴은 일반화된 해결책

                   입니다.)

          <3> 디자인 패턴은 객체지향 패러다임의 개념이 아닙니다.

                  (디자인 패턴에 대한 내용을 보면 객체지향 패러다임에 국한된 내용들이 많은데,

                   디자인 패턴이 반드시 객체지향에 적합해야 할 필요는 없습니다. 다만 객체지향이

                   굉장히 유용한 패러다임이기 때문에 연구가 많이 진행되었던 것입니다.)

          <4> 디자인 패턴이 필요한 이유는 많은 사람들이 이해할 수 있는 코드를 작성해야 많은 

                  사람들이 협업할 때 코드의 유지보수가 편해지고, 좀더 많은 사람들에게 설득력 있는

                  코드에 가까워 질 수있기 때문입니다.

 

     2) Gang of Four(4인방 패턴)

          <1> Creational(창조), Structural(구조), Behavioral(행동) 으로 구분합니다.

                  (클래스와 인스턴스에 관한 생성, 구조화, 행동과 관련이 있습니다. 여기서 디자인 패턴이

                   객체지향에 초점을 맞추고 있음을 알 수 있습니다.)

 

               1> Creational patterns(크리에이셔널 패턴)

                    1. Class 의 Instance 를 만드는 것과 관련있다.

                    2. Class creation patterns: 상속을 효과적으로 사용하는데 집중

                    3. Object creation patterns: Instance 를 효과적으로 생성하는데 집중( Delegation 활용 )

                    4. 대표적으로 Singleton(싱글톤) 패턴이 있습니다.

                         - Singleton patterns 이란 하나의 Class 에 단 하나의 Instance 를 허용하는 패턴입니다.

                         - Singleton 이란 하나의 Class 에 대해 애플리케이션이 시작될 때 최초 한번만 메모리를

                            할당하고, 그 메모리에 Instance 를 생성합니다. 즉, Instance 를 단 하나만 생성합니다.

                         - Singleton 의 '장점'은 고정된 메모리 영역을 얻어 하나의 Instance 만 생성하기 때문에

                            '메모리 낭비를 방지'하고, 'Instance 가 전역적으로 사용될 수 있기에 다른 Class 의

                            Instance 들이 데이터를 공유하고 변경할 수 있는 점' 입니다.

                         - Singleton 의 '단점'은 Singleton Instance 에게 많은 일을 위임하거나 데이터를 공유시킬

                            경우 다른 Class 간에 결합도가 높아져 개방폐쇄원칙에 위배되고, 멀티스레드 환경에서

                            '데이터 동기화 문제'가 발생할 수 있으므로 너무 많이 사용하지 않도록 하는게 좋습니다.

출처:&nbsp;https://jroomstudio.tistory.com/20

                         - 이런 싱글톤 방식은 생성자 앞에 private 가 선언되어 있기 때문에 다른 Class 에서 

                            new 키워드로 해당 Instance 를 생성할 수 없게 합니다. 접근 가능한 방법은 setter 와

                            getter 메서드를 통해서만 가능합니다.

                         - 위의 예제는 Activity 를 얻어오는 방식으로써 생명주기에 영향을 받을 수 있게 설계한

                            것입니다. 만약 생명주기에 영향을 받지 않도록 하려면 Application 레벨의 Context 를

                            받는 것으로 대체할 수 있습니다.

 

               2> Structural patterns(스트럭처 패턴)

                    1. Class 나 Instance 들의 관계와 관련있습니다.

                    2. 프로그램의 여러 기능들 간에 Interface 를 명확히합니다.

                    3. Class 나 Instance 의 관계를 조정하고 구조를 짜맞추는 패턴들이 포함됩니다.

                    4. 대표적으로 Adapter(어댑터) 패턴이 있습니다.

                        (외부와 접촉하는 Interface 가 불일치해 상호 접근이 불가한 객체들 사이에서 연결점이되어

                         두 객체를 연결해주는 역할을 합니다.)

                    5. Adapter 를 사용하는 대표적인 예는 RecyclerView(리사이클러뷰) 입니다.

출처:&nbsp;https://jroomstudio.tistory.com/20

                         - 리사이클러뷰는 데이터 목록을 아이템 단위의 뷰로 구성하여 화면에 표시하기 위해 

                            Adapter 를 사용합니다. 레이아웃의 형태로 Adapter 를 통해 만들어진 각 아이템 뷰는

                           뷰홀더 객체에 저장되어 화면에 표시되고 필요에 따라 생성 또는 재활용( Recycle ) 됩니다.

                         - Adapter 는 '리사이클러뷰에 표시될 아이템뷰를 생성'하는 역할과,

                           '사용자 데이터 리스트로부터 아이템뷰를 생성'하는 역할을 합니다.

                         - Layout Manager 는 어떤 형태로 아이템뷰룰 배치할 것인지를 결정합니다.

                         - ViewHolder 는 화면에 표시될 아이템뷰를 저장하는 객체 입니다.

출처:&nbsp;https://jroomstudio.tistory.com/20

                         - 아래는 Main Activity 에서 출력하는 예제 입니다.

출처:&nbsp;https://jroomstudio.tistory.com/20

 

               3> Behavioral patterns(비헤이비어 패턴)

                    1. Class 와 Instance 가 동작하는 방식이나 소통하는 방식과 관련이 있습니다.

                    2. 객체 속 작업이 진행되는 작업 흐름을 정의하고 따라갑니다.

                    3. 알고리즘이나 기능들이 어떻게 흐르는지, 어떤 순서로 소통하는 지에 대해 정의합니다.

                    4. 대표적으로 Template Method 패턴이 있습니다.

                         - Template Method 패턴은 어떤 동작의 알고리즘을 단위 기능 모듈로 분류하고 이들간의

                           동작 순서를 정의한다. 그리고 나서 단위 기능을 바로 구현하는 것이 아니라 몇몇은

                           그 Class 를 상속할 자식 Class 에 위임합니다.

                       

출처:&nbsp;https://jroomstudio.tistory.com/20

                         - 위의 예제처럼 자동 변속하는 자동차 Class 가 있고 수동 변속하는 자동차 Class 가 

                           있을 때 둘다 playWithOwner() 메서드를 통해 동일하게 구현되어 있지만 수동기어인지

                           자동기어인지에 대해서 서로 다릅니다.

                           이런 경우에 Template Method Pattern 을 사용하여 설계할 수 있습니다.

                         - 한꺼번에 구체적인 클래스를 구현하지 않고 추상클래스의 탬플릿 메서드를 구현하여서

                           구체적인 Class 가 이를 상속받아 자신이 필요한 메서드를 작성해주는 방식입니다.

출처:&nbsp;https://jroomstudio.tistory.com/20

                         - 이런식으로 추상클래스 안에 추상메서드 선언을 해놓고 일반적인 메소드를 어느정도 

                            구현해 놓고, 추상클래스를 상속받은 구체적인 Class 가 오버라이딩 해서 재정의 하는

                            방식입니다.(오버라이딩 해도되고 안해도 됩니다.) 이러한 메서드는 Hook 메서드라고

                            합니다. stopBreak() 가 Hook 에 해당됩니다.

                         - 상위 Class 에게 공통적인 로직은 템플릿 메서드로 두고, 구체적인 클래스에서 스타일에

                            맞게 구현을 강제하기 위해 추상메서드를 사용하고, Hook 메서드를 두는 패턴을

                            Template Method Pattern(템플릿 메서드 패턴) 이라고 합니다.

 

     3) 아키텍처 패턴

          <1> MVC Pattern

               1> MVC( Model - View - Controller ) 는 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴

                    입니다. 이 패턴을 성공적으로 사용하면, 사용자 인터페이스로부터 비즈니스  로직을 쉽게

                    분리하여 애플리키에션의 시각적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이

                    쉽게 고칠 수 있는 애플리케이션을 만들 수있습니다.

 

               2> MVC 구성요소

                    1. Controller: 데이터와 비즈니스 로직 사이의 상호 동작을 관리합니다.(사용자로부터 입력을

                                           받고, Model 을 거쳐서 View 를 업데이트 합니다.)

                    2. Model: 애플리케이션의 정보, 데이터를 나타냅니다.

                    3. View:  사용자 인터페이스 입니다.(텍스트, 버튼, 체크박스 등등)

                        (비즈니스 로직이란 프로그램에서 실세계의 규칙에 따라 데이터를 생성, 표시, 저장, 변경

                         하는 부분을 말합니다.)

 

               3> MVC 관계도

출처:&nbsp;https://bictoselfdev.blogspot.com/2021/05/mvc.html

               4> MVC 주요 포인트

                    1. Android 에서는 기본적으로 View 와 Controller 가 공존합니다.( Activity 또는 Fragment )

                    2. Model 은 따로 분리하여 새로운 Class 로 관리합니다.

                    3. 사용자가 발생한 Event 에 따라서 Controller 에서 Model 상태를 업데이트 해줍니다.

                    4. 변경된 Model 상태는 View 를 통해 사용자에게 알려줍니다.

출처:&nbsp;https://jroomstudio.tistory.com/21?category=386216

               

               5> MVC 특징

                    1. Activity 또는 Fragment 에서 모든 동작을 처리하기 때문에 쉽게 구현이 가능하지만,

                        그 만큼 한 Class 에 코드양이 방대해질 수 있기 때문에 유지보수가 어려울 수 있습니다.

 

               6> MVC 장점

                    1. 개발기간이 감소 됩니다.

                        (Activity 에서 모든 동작을 처리해주면 됩니다.)

                    2. 코드 분석이 용이합니다.

                        (코드가 한곳에 모여있기 때문에 가독성에 유리할 수 있습니다.)

 

               7> MVC 단점

                    1. 하나의 Class 에 코드양이 증가합니다.

                        (Activity 하나에서 모든 기능을 구현할 수 있기 때문에 코드양이 많아집니다.

                    2. 유지보수가 어렵습니다.

                    3. View 와 Model 의 결합도가 상승합니다.

                        (대부분의 코드가 View 에서 Model 을 직접 호출하는 방식을 사용하기 때문에 결합도가

                         높아집니다.)

                    4. 테스트코드의 작성이 어렵습니다.( UI 변경위주의 테스트 코드는 가능하지만, Model 을

                        변경하게 될 경우 복잡해집니다.

 

          <2> MVP Pattern

               1> MVP( Model - View - Presenter ) 는 Android 에서 MVC 패턴의 Controller 와 View 가 공존하는

                    문제점을 해결한 패턴으로써, Android 에서 가장 많이 사용하는 패턴입니다.(2020년도 기준)

 

               2> MVP 구성요소

                    1. Model: Data 와 관련된 처리를 합니다.( MVC 의 Model 과 동일합니다.)

                    2. View: 이벤트가 발생하면 Presenter 로 알립니다.

                    3. Presenter: View 에서 전달받은 이벤트를 처리하여 다시 View 로 반환합니다.

 

               3> MVP 관계도

출처:&nbsp; https://velog.io/@seokgyuhong/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%ED%8C%A8%ED%84%B4-MVP

               4> MVP 주요포인트

                    1.  Android 에서는 기본적으로 View 와 Controller 가 공존하므로 View/Controller 라고

                         명시되어 있지만, MVP 패턴에서는 Controller 의 역할이 분리되어  있어서

                         View/Controller 는 View 에 관련된 역할만을 수행합니다.

                    2. Presenter(프리젠터) 는 View/Controller 가 전달해준 이벤트를 수신하고 이벤트 형태에

                         맞게 Model에 데이터를 요청합니다.(MVC 에서 Controller 의 역할을 수행한다고

                         생각하면 될 것 같습니다.) 그리고 Model 에서 전달받은 데이터를 가공하여

                         View/Controller 에게 전달합니다.

                    3. 나머지는 기본적으로 MVC 와 동일합니다.

출처:&nbsp;https://jroomstudio.tistory.com/22?category=386216

 

 

               5> MVP 특징

                    1. MVP 패턴에서는 Activity 와 Fragment 가 View 의 일부로 간주됩니다.

                        그렇기 때문에 Activity 와 Fragment 는 유저 액션 이벤트를 Presenter 로

                        전달하는 역할만을 수행합니다.

                    2. Presenter 는 Model 과 View 의 가운데에서 상호작용 관리를 하며 내용상 MVC 의

                        컨트롤러와 동일하지만 View 에 연결되지 않은 단순 Interface 라는 점에서 차이가 

                        있습니다.

 

               6> MVP 장점

                    1. MVC 와는 다르게 코드가 매우 깔끔해지며 MVP 를 이용해서 이와 같이 Model 과

                        View 간의 결합도를 낮추면, 새로운 기능 추가 및 변경을 해야 할 때 관련된 해당

                        부분의 코드만 수정하면 되기 때문에 확장성이 좋아짐과 동시에 유닛 테스트 시

                        테스트 코드를 작성하기 편리해지기 때문에 더 쉽게 안전한 코딩이 가능해집니다.

                    2. 그리고 UI, Data 각각 파트를 나누기 때문에 해야 할 일이 명확해지고 그 결과로

                        쉽고 빠르게 코딩이 가능합니다. 

 

               7> MVP 단점

                    1. MVP 의 가장 큰 단점은 애플리케이션이 복잡해질수록 View 와 Presenter 사이의 

                        의존성이 강해지는 단점이 있습니다.

                     2. 그리고 MVC 의 Controller 처럼 Presenter 도 어느정도 시간이 지남에 따라 추가 

                         비즈니스 로직이 집중되는 경향이 있습니다. 그래서 시간이 지날수록 거대해지며

                         동시에 다루기 어렵고, 문제가 발생하기 쉬우며, 서로 간의 분리를 하기도 어려워지게

                         됩니다.

 

          <3> MVVM Pattern

               1> MVVM( Model - View - ModelView ) 은 하나의 소프트웨어를 최대한 기능적으로 작은

                    단위로 나누어 테스트가 쉽고 큰 프로젝트도 상대적으로 관리하기가 좋은 구조입니다.

                    View 와 Model 을 연결하기 위해 사용해야하는 연결 코드를 감소시킵니다.

                    MVP 패턴에서 파생되었고, Microsoft 에 의해 제안된 패턴 입니다.

 

               2> 구성요소

                    1. Model: MVC, MVP 와 동일합니다.

 

                    2. View: View 는 기본적으로 데이터를 보여주기만 해야 해서 비즈니스 로직을 포함하지

                                  않지만 UI 변경과 관련된 일부 로직은 포함될 수 있습니다.(안드로이드는 다른

                                  플랫폼과는 다르게 생명주기( LifeCycle ) 라는 특수한 순서를 가지고 있기 때문에

                                  이것을 처리하는 것만으로도 View 는 상당히 복잡해지기 때문입니다.)

                                  View 는 ViewModel 을 관찰하고 있다가 상태 변화가 전달되면 화면을 갱신합니다.

 

                    3, ViewModel: 모든 View 와 관련된 비즈니스 로직이 들어가게 되며, 데이터를 잘 가공해서 

                                           View 에 뿌리기 쉬운 Model 로 바꾸는 역할을 합니다. View 와 ViewModel 은

                                           MVP 와는 다르게 1:N 의 관계를 가질 수 있으며, 여러개의 Fragment  가

                                           하나의 ViewModel 을 가질 수있습니다. ViewModel 은 View 가 

                                           데이터 바인딩( Data Binding ) 할 수 있는 속성과 명령으로 구성되어

                                           있습니다. 

 

               3> 관계도

출처:&nbsp;https://velog.io/@bang/Android-MVVM-pattern-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0

 

               4> 주요포인트

                    1. ViewModel 은 Model 을 알지만 View 를 알지 못합니다.

                    2. View 는 Model 을 알지 못하지만 ViewModel 은 알 수 있습니다.

                    3. View 는 ViewModel 을 관찰하고 있다가 변화가 감지되면 화면을 갱신합니다.

                    4. ViewModel 은 기본적으로 View 에 종속시키면 안됩니다.

 

               5> 특징

                    1. MVVM 을 아무런 도움없이 구현하면 기존의 문제점을 개선하는 과정에서 새로운 

                        문제가 발생할 수 있습니다. 그렇기 때문에 DataBinding 이라는 툴을 이용하여

                        View 와 ViewModel 간의 의존성을 낮춰서 사용해야 합니다.

                     2. DataBinding 은 View 와 ViewModel 간의 데이터와 명령을 연결해주는 매개체가 되어

                         서로의 존재를 명확히 알지 못하더라도 상호작용 할 수 있도록 도와줍니다.

                         Model 에서 데이터가 변경되면 ViewModel 을 거쳐 View 로 전달되도록 하며 

                         Android 에서는 LiveData 혹은 RxJava 등을 통해 구현할 수 있습니다.

출처:&nbsp;https://jroomstudio.tistory.com/24?category=386216

 

               6> 장점

                    1. Model 과 View 사이, ViewModel 과 view 사이의 의존성이 없으므로 유닛 테스트가 더 

                        쉬워지며 MVP 패턴에서처럼 테스트를 위한 가상 뷰를 만들 필요 없이, 테스트할 때 

                        Model 이 변경되는 시점에 옵저버블(관찰) 변수가 제대로 설정됐는지 확인하면 됩니다.

                    2. DataBinding 라이브러리를 이용함으로써 서로간의 의존성을 낮추고, 유닛 테스트를

                        더욱 쉽게 작성할 수 있고 UI 코드는 네이티브 코드에 관여하지 않아도 됩니다.

                    3. 중복되는 코드를 모듈화 할 수 있습니다.

 

               7> 단점

                    1. View 가 변수와 표현식 모두에 Binding 될 수 있으므로 시간이 지남에 따라 관계없는

                        Presentation Logic 이 늘어나고 이를 보완하기 위해 XML 에 코드를 추가하게 됩니다.

                        이때 난해하게 코드가 증가된다면 유지보수 단계에서 어려움을 겪을 수있습니다.

                    2. 또 ViewModel 을 설계하기가 어려운 문제도 있습니다. 

                        (그래도 다행히 요즘은 잘 설계된 구조가 샘플 코드로 많이 나와있기 때문에 해결이

                         가능합니다.)

 

 

참고자료:

https://developer.android.com/guide/platform?hl=ko

 

https://nobase-dev.tistory.com/281

 

위키피디아

 

https://jroomstudio.tistory.com/20

 

https://bictoselfdev.blogspot.com/2021/05/mvc.html

 

https://jroomstudio.tistory.com/21?category=386216

 

https://jroomstudio.tistory.com/24?category=386216

 

https://velog.io/@seokgyuhong/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%ED%8C%A8%ED%84%B4-MVP

 

https://velog.io/@bang/Android-MVVM-pattern-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0