Clean Architecture : Part 2 - The Clean Architecture
아키텍처 관점에서 마지막이자 가장 중요한 레이어는 엔티티 또는 도메인 레이어에요. 엔티티는 핵심 비니지스 규칙을 캡슐화해요. 핵심 비지니스 규칙은 비지니스의 존재에 필수지만, SW 시스템에 필수는 아니에요. 외부 변경은 이 레이어의 동작에 그 어떤 영향을 주면 안되요. SW 시스템 또는 어플리케이션이 없어도 타당한 비지니스 규칙을 구현하는 엔티티를 만들 수 있어요. 기술적인 관점에서 엔티티는 단지 데이터 만이 아니라 메소드와 로직을 포함하는 객체에요. 엔티티는 DTO (Data Transfer Object) 와 DAO (Data Access Object) 가 아니에요.
These arrows represent code level dependencies which means the code where an arrow starts knows about the code the arrow is pointing to. All these arrows fulfill the Dependency Rule as all arrows crossing the boundaries are always going from left to right - from the framework circle to the interface adapters circle to the use case circle.
Implementing Clean Architecture - Of controllers and presenters
Use Case interactor 는 input-port는 implements 하고 output-port는 인자로 사용
→ interface를 사용하는 이점
Thoughts on Clean Architecture
interface SomeRepository {
fun doSomething()
}
class SomeViewModel1(private val someRepository: SomeRepository) {
//...
fun doSomething() {
//...
someRepository.doSomething()
//...
}
//...
}
class SomeViewModel2(private val someRepository: SomeRepository) {
//...
fun doSomething() {
//...
someRepository.doSomething()
//...
}
//...
}
class SomeViewModel3(private val someRepository: SomeRepository) {
//...
fun doSomething() {
//...
someRepository.doSomething()
//...
}
//...
}
If the requirements for the repository change, let’s say the doSomething method now needs a model coming from a SomeOtherRepository, how much code do you need to change? How many ViewModels are affected?
The "Real" Repository Pattern in Android
Entity: An entity is a plain object that has an identity (ID) and is potentially mutable.
→ 회사) OutputFlow에서만 사용한다. VO형태로 동작(조작 불가능한 형태?)
Value object: immutable object without identity.
Aggregate root (DDD only): Entity that binds together with other entities (basically a cluster of associated objects).
[DAO] DAO, DTO, Entity Class의 차이 - Heee's Development Blog
// Network DTO
data class NetworkProduct(
@SerializedName("id")
val id: String?,
@SerializedName("name")
val name: String?,
@SerializedName("nowPrice")
val nowPrice: Double?,
@SerializedName("wasPrice")
val wasPrice: Double?
)
// Entity
data class Product(
val id: String,
val name: String,
val price: Price
) {
// Value object
data class Price(
val nowPrice: Double,
val wasPrice: Double
) {
companion object {
val EMPTY = Price(0.0, 0.0)
}
}
}
// Database DTO
@Entity(tableName = "Product")
data class DBProduct(
@PrimaryKey
@ColumnInfo(name = "id")
val id: String,
@ColumnInfo(name = "name")
val name: String,
@ColumnInfo(name = "nowPrice")
val nowPrice: Double,
@ColumnInfo(name = "wasPrice")
val wasPrice: Double
)
개발자인 나에게 중요한 것은 Use Case 가 정확하게 동작하는 것임. Use Case 동작 결과를 확인하는데 UI 가 필요함? 아님!! 테스트 프레임워크로 Use Case 실행 결과를 확인 할 수 있음.