본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Effective Kotlin] Item 5 : Specify your expectations on arguments and state

by 돼지왕 왕돼지 2022. 2. 19.
반응형

이 글은 Effective Java 를 완독하고, Kotlin 을 상용으로 사용하는 개발자 입장에서
Effective Kotlin 글 중 새로운 내용, remind 할 필요 있는 부분, 핵심 내용 등만 추려 정리한 내용입니다.

#
기대하는 바가 있다면 선언하라.
Kotlin 에서는 다음과 같은 기능을 지원한다.
    require block : argument 에 대한 기대
    check block : state 에 대한 기대
    assert block : true 에 대한 기대
    elvis operator with return or throw

 

#

fun pop(num: Int = 1): List {
	require(num <= size) {
		"Cannot remove more elements than current size"
	}
    
	check(isOpen) { "Cannot pop from closed stack" }

	val collection = innerCollection ?: return emptyList()
	
    val ret = collection.take(num)
	innerCollection = collection.drop(num)
	assert(ret.size == num)
	return ret
}

위와 같은 선언을 해줌으로써 문서화를 하지 않아도 되는 장점이 있다.
위 조건을 충족하지 않으면 exception 이 발생한다.
그리고 위의 체크들에 의해 smart-casting 도 작동한다.

 

 

Arguments

#
argument 에 대한 요구사항 명시는 주로 'require' 로 한다.
requireNotNull 과 같은 변형된 형태도 있다.

fun factorial(n: Int): Long{
	require(n >= 0)
	return if (n <= 1) 1 else factorial(n - 1) * n
}

require 는 그 요구사항을 충족하지 못했을 때 IllegalArgumentException 을 던진다.

 

#
lambda 를 통해 msg 도 전달할 수 있다.

require(n >= 0) { "Cannot calculate factorial of $n because it is small than 0" }

 

 

State

#

fun speak(text: String){
	check(isInitialized)
}

checkNotNull 과 같은 변형도 있다.

require 과의 차이점은 요구사항 위배시 IllegalStateException 을 던진다.
require 와 마찬가지로 lazy msg 를 설정할 수 있다.

 

 

Assertions

#
제대로 구현이 되었다면 true 여야만 하는 것들이 있을 수 있다.
그것들을 검증할 때 테스트 코드를 작성하며 assert 를 쓰는 것이 좋다.
production 에서는 실제 assert 가 어떤 영향을 미치지 않는 것이 default 이다. JVM 옵션을 통해 이를 on/off 할 수 있다.

 

#
코드 안의 critical 한 내용 검증이라면 assert 대신 check 를 사용하는 것을 권장한다.

 

 

Nullability and smart casting

 

 

Summary

#
요구사항을 더 잘 보이게 하고, 체크를 통해 앱의 안정성을 올려라.
코드가 올바르게 동작하도록 보호하고, smart cast 의 효과도 보자.

 

#
require, check, assert, elvis operator with return or throw 를 사용하라.

 

 

 

반응형

댓글