도메인 로직을 도메인레이어에 작성 할 수 있을까 에 대해 많이 고민을 했고, 그 해답을 공유 할 것
함수형 프로그래밍 / 객체지향 프로그래밍 둘 다 활용 가능
불변 객체란 무엇일까 ?
변하지 않는
객체
변경 할 수 없는
객체 ?
val mutableList = mutableListOf()
mutableList
는 불변객체인가 ?val mutableNumbers = mutableListOf()
val numbers: List<Int>
get() = mutableNumbers
val mutableNumbers = mutableListOf()
val numbers: List<Int>
get() = mutableNumbers.toList()
방어적 전파
/ 방어적 복사
라는 키워드로 검색해보면 좀 더 많은 정보가 있음방어적 복사
왜 방어적 복사를 하는걸까 ?
data class User(val name: String, val email:String) {
init {
require(name.isNotBlank())
require(isValidEmail(email))
}
private fun isValidEmail(email: String): Boolean
}
위 코드처럼 짜면 장점
class SomethingRepository {
fun doSomething(name: String, email: String) {
TODO()
}
}
class SomethingRepository {
fun doSomething(user: User) {
TODO()
}
}
불변객체를 통해 가독성 올리기
data class Book(
val name: String,
val publishedAt: LocalDateTime,
val type: BookType
)
enum class BookType {
Cartoon ...
}
class BookViewModel : ViewModel() {
private val _books = MutableLiveData ...
val books: LiveData<List<Book>>
get() = _book
}
class BookViewModel : ViewModel() {
private val _books = MutableLiveData ...
val books: LiveData<List<Book>>
get() = _book
val cartoonBooks = _books.map ...
}
fun List<Book>.filterCartoon(): List<Book> {
return filter { it.type == BookType.Cartoon }
}
val cartoonBooks = _books.map(::filterCartoon)
data class Books(
private val values: List<Book>
) {
fun filterCartoon(): Books {
return Books(values.filter { it.type == BookType.Cartoon })
}
}
val cartoonBooks = books.map(Books::filterCartoon)
data class CartoonBooks() ...
data class LatestBooks() ...
주의사항 & 팁
네이밍
Books ? / Library ? / BookInfo ? ...
뭘로 이름을 짓지 상세히 고민해볼것
추천하지 않는 방식
data class Books(
private val values: List<Book>
) : List<Book> by values
방어적 복사 후 List 반환
data class Books(
private val values: List<Book>
) {
fun toList(): List<Book> = books.toList()
companion object {
fun of() ...
}
}