체이닝 (Chaining)
- 메서드 호출을 연속적으로 이어붙이는 패턴
- 각 메서드가 객체 자신을 반환 (보통
this
또는 apply
사용)
- 주로 객체 설정이나 데이터 처리 파이프라인에 사용
커링 (Currying)
- 여러 인자를 받는 함수를 단일 인자를 받는 함수들의 체인으로 변환
- 각 단계가 다음 함수를 반환
- 함수의 부분 적용과 재사용성을 높이는데 사용
체이닝 상세 설명
기본 구조
class ChainExample {
var value: Int = 0
fun addValue(x: Int) = apply {
value += x
}
fun multiplyBy(x: Int) = apply {
value *= x
}
fun clear() = apply {
value = 0
}
}
// 사용 예시
val result = ChainExample()
.addValue(5)
.multiplyBy(2)
.addValue(3)
println(result.value) // 13
안드로이드에서의 실제 사용
// View 설정
binding.titleText.apply {
text = "제목"
textSize = 20f
setTextColor(Color.BLACK)
isVisible = true
}
// RecyclerView 설정
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = UserAdapter()
addItemDecoration(DividerItemDecoration(context, LinearLayoutManager.VERTICAL))
}
커링 상세 설명
기본 커링 함수
// 3개의 파라미터를 받는 함수를 커링하는 확장 함수
fun <P1, P2, P3, R> ((P1, P2, P3) -> R).curried(): (P1) -> (P2) -> (P3) -> R =
{ p1: P1 -> { p2: P2 -> { p3: P3 -> this(p1, p2, p3) } } }
// 사용 예시
val originalFunction = { a: Int, b: String, c: Boolean ->
"$a - $b - $c"
}
val curriedFunction = originalFunction.curried()
// 단계별 실행
val step1 = curriedFunction(1) // Int 인자 적용
val step2 = step1("Hello") // String 인자 적용
val result = step2(true) // Boolean 인자 적용
println(result) // "1 - Hello - true"
// 한번에 실행
val oneShot = curriedFunction(1)("Hello")(true)
println(oneShot) // "1 - Hello - true"
실제 활용 예시
// API 요청 함수를 커링으로 구현
data class ApiConfig(
val baseUrl: String,
val apiKey: String,
val timeout: Int
)
val makeApiRequest = { config: ApiConfig ->
{ endpoint: String ->
{ params: Map<String, String> ->
// API 요청 구현
"$config - $endpoint - $params"
}
}
}
// 설정 단계별 적용
val withConfig = makeApiRequest(ApiConfig("<https://api.example.com>", "key123", 5000))
val userApi = withConfig("/users")
val result = userApi(mapOf("id" to "123"))
// 로깅 시스템 예시
val createLogger = { tag: String ->
{ level: String ->
{ message: String ->
when (level) {
"DEBUG" -> "D/$tag: $message"
"ERROR" -> "E/$tag: $message"
else -> "I/$tag: $message"
}
}
}
}
val userLogger = createLogger("UserActivity")
val debugLogger = userLogger("DEBUG")
println(debugLogger("User logged in")) // "D/UserActivity: User logged in"
실제 활용: 체이닝과 커링 조합
// 체이닝으로 구현된 빌더에 커링 적용
class RequestBuilder {
private var baseUrl: String = ""
private var method: String = "GET"
private var headers: Map<String, String> = emptyMap()
fun setBaseUrl(url: String) = apply { baseUrl = url }
fun setMethod(m: String) = apply { method = m }
fun setHeaders(h: Map<String, String>) = apply { headers = h }
fun build() = { endpoint: String ->
{ params: Map<String, String> ->
// 실제 요청 구현
"$method $baseUrl$endpoint - $params - $headers"
}
}
}
// 사용 예시
val apiRequest = RequestBuilder()
.setBaseUrl("<https://api.example.com>")
.setMethod("POST")
.setHeaders(mapOf("Authorization" to "Bearer token"))
.build()
val usersEndpoint = apiRequest("/users")
val result = usersEndpoint(mapOf("id" to "123"))