✅ Clean Architecture
- 유지보수와 확장성에 좋은 프로젝트 구성 방법
- 한 가지 컴포넌트에는 한가지 고려사항만!
- 구현 레이어는 추상 레이어에 의존한다
- 클린 아키텍처는 모바일 개발에만 국한되는 것이 아니라 어떠한 소프트웨어 프로젝트에도 적용된다.
Use Cases 레이어는 Entities 레이어에 의존한다.
Entities : 비즈니스 룰
Use Cases : 어떻게 entities를 사용할 지
Controllers/Presenters/Gateways : 데이터를 수정하고 유저에게 보여줄 데이터를 준비
Devices/Web/UI/DB/External Interfaces : 어떻게 데이터를 표시해줄 지
❗️ 클린 아키텍처의 장점
- 엄격한 아키텍처 - 실수하기 어려움
- 비즈니스 로직의 캡슐화 (사용하기 쉽고 테스트에 용이)
- 캡슐화를 통한 의존성의 강제화
- 병렬 시스템 개발이 가능 (모든 컴포넌트들이 분리되어있음)
- 규모가 큰 프로젝트도 더이상 복잡하지 않음
- 코드를 이해하기 쉽고 유지보수하기 좋음
- 테스팅하기 쉬움
Entities
가장 추상적인 레이어
- Domain objects
- Foundational business logic
- POJOs (plain old java object)
Use cases
entities 위에서 수행될 수 있는 행위들
android system에 의존하지 않음
블랙박스로 생각하면 이해하기 쉬움(데이터를 넣고 빼지만, 그 데이터가 어디에 사용되는지는 정확히 모름)
input = entities, output = 무엇이든지
- Actions that can be taken on the entities
- Depend on entities
- Business logic, plain code
- No other dependencies
- A use case doesn't know how the result is going to be used
Controllers, Presenters, Adapters
(유즈 케이스에서 가져온 데이터)아무거나 넣고 데이터를 한 형태에서 다른 형태로 변환해줌
그 변환한 데이터를 상위 레벨 레이어에 보여준다
- Interfaces
- Retrieve data from various sources
- Present data in a specific format (ex: XML, JSON, ...)
- Depend on lower level layers
Infrastructure
어떻게 데이터가 해석되고 보여질지 결정
인터페이스 변경이 생기면 이 레이어도 변함
- How the data is interpreted and presented
- Most volatile layer, likely to change
- Interacts with interfaces to retrieve data
- UI, Frameworks, devices etc
✅ SOLID principles
Single responsibility
Open-closed
Liskov substitution
Interface segregation
Dependency inversion
Single responsibility
한 가지 클래스(컴포넌트)는 한 가지 일을 해야 한다.
- A class should only have one job
- One reason to change
- If there are two reasons to change, it should be split into two different classes
Open-closed
컴포넌트들은 확장을 위해 open되어야 하지만, 변경에 대해서는 closed되어야 한다.
프로젝트에 새로운 기능을 추가하려면 컴포넌트를 변경해서는 안된다.
대신에 컴포넌트나 클래스를 확장하거나 확장 클래스에 새로운 기능을 추가해야한다.
- Open for extension, closed for modification
- If new functionality needs to be added, it should be added to an extension of the class
- Abstract away stable functionality
- Put volatile functionality in extension classes
Liskov substitution
낮은 레벨의 클래스들은 높은 레벨에 영향을 주지 않고 대체될 수 있다.
- Low level classes can be substituted without affecting higher levels
- Achieved using abstract classes and interfaces
Interface segregation
여러개의 구체적인 인터페이스들은 한가지의 일반적인 인터페이스보다 좋다.
한 가지의 컴포넌트가 여러개의 일을 하는 것을 원치 않는다.
- Use interface to advertise functionality
- Many specific interfaces are better than one generic interface
- An interface only exposes the methods that the dependent class needs not more
Dependency inversion
구상 클래스는 추상 클래스에 의존하지만, 반대로는 안된다.
activity나 fragment 같은 안드로이드 컴포넌트들은 비즈니스 로직에 의존한다.
- Concrete classes depend on abstract classes not the other way around
- Volatile functionality depends stable functionality
- Framework specific functionality depends on business logic
✅ Project structure
그렇다면 어떻게 클린 아키텍처를 안드로이드 프로젝트에 적용할까?
MVVM
Model - View - ViewModel
Model - business logic and data
View - the way that data is displayed for the user (activities, fragments, adapters), responsible for the UI
ViewModel - make the connection between the View and Model, async callbacks
❗️ 안드로이드 프로젝트에서 MVVM을 사용하는 이유?
클린 아키텍처와 잘 어울리기도 함
- Supported by Google, part of Android Jetpack
- ViewModel integrates well with the Activity/Fragment lifecycle
- LiveData provides async communication with the View