1-1. 클린 아키텍처란?
클린 아키텍처
클린 아키텍처의 개념은 우리가 잘 알고 있는 Uncle Bob인 로버트.C 마틴의 Clean Architecture에서 시작되었습니다.

1-2. 클린 아키텍처의 구조 및 특징

Dependecy Rule
하위 계층으로 갈수록 상위 계층을 몰라야 합니다. 내부 원의 어떤것도 외부 원의 어떤것에 대해 전혀 알 수 없습니다.
특히, 외부 원에 선언된 이름(class, function, variable 등)은 내부 원에 있는 코드에서 언급되지 않아야 합니다.
CA의 각 계층
- Entities : 비지니스 규칙(business rule) (예: 근무시간에 따라 급여를 계산하는 공식, 직원에 대한 가장 기본적인 데이터가 들어있는 POJO)
- Use cases : 단순히 실행 가능한 작업. Intereactor라고도 함. android에서는 UI와 상호작용하여 Repository에서 데이터를 꺼내온다. getRandomFactUseCase등 이름으로 기능을 알수 있어야 한다.
- Presenters(Interface Adapters) : 데이터를 Entity, UseCase의 편리한 형식에서 데이터베이스 및 웹에 적용 할 수 있는 형식으로 변환한다. MVP의 Presenter, MVVM의 ViewModel으로, UI에서만 사용된다.
- Frameworks & Drivers : 데이터베이스나 Web Framework, UI등
안드로이드 클린아키텍처 구조

총 3개의 계층이 존재하게 된다, Data -> Domain -> Presentation 각 레이어는 의존성 주입을 역으로 해주는 구조를 가지고 있다. 그리고 꼭 한방향만 지향한다
- presentation layer : data를 화면에 표시하고 user 상호작용을 다룸. UI, Presenter, ViewModel등.
- domain layer : 비지니스 프로세스와 관련된 가장 핵심 계층. 어떤 다른 계층에도 독립적임. Entities, Use Case, Repository Interface등.
- data layer : 어플리케이션의 데이터 관리(네트워크에서 데이터 검색, 데이터 캐시 관리 등). Repository Implementation, Local & Remote Data source등.
핵심은 (dependency rule에 따르면)domain 계층이 다른 계층에 독립적이라는 것입니다.

domain 계층에서는 다른 외부 계층에서 정의된 클래스에 접근하지 않아야 합니다.
이상적으로는, 도메인 계층은 라이브러리 및 프레임 워크와 독립적이여야 합니다.
Kotlin Standard Library나 몇가지 DI(Dependecy Injection) library는 괜찮지만, 다른 라이브러리나 framework (특히 Android Framework)는 피해야 합니다.
2-1. 기초 구현
Memo ToDoApp을 만들기 위해 Clean Architecture를 지향하여 만들었다.

우선 계층 3개의 Package를 설정하여 각 레이어에 맞는 구축을 해주어야 한다.
- Data에는 Entity Model과 RoomDatabase를 구축하여 Repository화 해준다

- ViewHolderList를 구축하여 RecyclerView 형태로 아래와 같이 보이도록 구현을 해주었다.

viewholder_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
app:cardCornerRadius="20dp"
app:cardElevation="4dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="6dp">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:layout_alignParentLeft="true" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="4dp"
android:layout_marginTop="2dp"
android:layout_toEndOf="@+id/checkbox"
android:orientation="vertical"
android:layout_marginLeft="4dp"
android:layout_toRightOf="@+id/checkbox">
<TextView
android:id="@+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:text="Codelia"
android:maxLines="5"
tools:text="Title"
android:textColor="@android:color/black"
android:textSize="24sp"
android:textStyle="bold"/>
<TextView
android:id="@+id/cityTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Descript"
android:textSize="18sp"/>
</LinearLayout>
<Button
android:id="@+id/statusTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="6dp"
android:layout_marginRight="6dp"
android:text="Delete"
android:textSize="20sp"
android:textStyle="bold"
android:background="@drawable/button_stroke"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:text="List"
android:textColor="@android:color/black"
android:textSize="36sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listRecyclerView"
tools:listitem="@layout/viewholder_memo_item"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginLeft="1dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="1dp"
android:layout_marginRight="1dp"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleTextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
Clean Architecture 형식의 구현을 하기위에 가장 기초적인 View화 RoomDB구조를 구현해주었다.
다음은 Domain Usecase설정과 Recyclerview를 설정해주는 adapter구현, presentation의 Viewmodel을 통한 LiveData를 Observing하는 구조를 구현해보아야겠다.
'안드로이드 > 앱개발(Android)' 카테고리의 다른 글
| android) KaKao Open Api 책 검색 앱 만들기 - 1 (0) | 2022.09.13 |
|---|---|
| 안드로이드 앱개발 ) 마켓컬리 공모전 (0) | 2022.09.05 |
| (Android) 심리테스트 앱 - 직접 구현해보기 (1) (0) | 2022.04.08 |
| (Android) OTT 앱 (0) | 2022.03.08 |
| (Android) 음악스트리밍 앱 (0) | 2022.02.20 |