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

[Effective Kotlin] Item 34 : Consider a primary constructor with named optional arguments

by 돼지왕왕돼지 2022. 5. 6.
반응형

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

 

Telescoping constructor pattern

#
Kotlin 에서는 default arguments 지정으로 primary constructor 하나만 정의하면서 이를 대체할 수 있다.

 

 

Builder pattern

#
default argument & named parameter 조합이 builder 보다 좋다.

  1. 코드가 더 짧고, 수정도 더 간단하다.
  2. 훨씬 깔끔하다. 어떻게 object 가 생성되는지는 constructor 하나만 보면 된다.
  3. 사용하기가 더 쉽다. primary constructor 는 built-in 컨셉이기 때문이다. 그리고 개발자가 build 함수 호출을 잊을 가능성도 있다.
  4. 동시성 이슈가 없다. function param 은 immutable 인데 반해, builder 의 property 는 대부분 mutable 이다. 그래서 thread-safe 이슈가 발생할 수도 있다.

 

#
위에서 명시한 장점들 때문에 builder 를 기피해야 한다는 것은 아니다. builder 패턴이 빛을 발하는 경우도 있다.

val dialog = AlertDialog.Builder(context)
	.setMessage(R.string.dialog_msg)
	.setPositiveButton(R.string.yes) { dialog, id ->
		// ...
	}
	.setNegativeButton(R.string.cancel) { dialog, id ->
		// ...
	}

 

이를 constructor 로 바꾸면..

val dialog = AlertDialog(context,
	message = R.string.dialog_msg,
	positiveButtonDescription = ButtonDescription(R.string.yes){ dialog, id ->
		// ..
	},
	negativeButtonDescription = ButtonDescription(R.string.cancel){ dialog, id ->
		// ..
	}

이런 형태는 Kotlin community 에서 부정적으로 받아들여진다.

 

위와 같이 constructor 형태로 사용하려면, DSL 을 사용하는 것이 추천된다.

val dialog = context.alert(R.string.dialog_msg){
	positiveButton(R.string.yes){
		// ...
	}
	negativeButton(R.string.cancel){
		// ...
	}
}

이런 형태가 builder 보다 더 선호된다. 더 유연하며 깔끔한 기술 형태이기 때문이다.

그러나 DSL 은 정의하기가 어렵다는 단점이 있다. 그러나 Builder 도 마찬가지로 어렵다는 것을 인지하자.

 

#
Builder 의 또 다른 장점은 factory 로서 사용될 수 있다는 것이다.

 

#
Kotlin 세계에서 Builder 패턴이 best option 일 때는 거의 없다.
선택된다면 아래의 이유일 것이다.

  1. library 와 코드 스타일을 맞추기 위해
  2. DSL 을 지원하지 않는 다른 언어와 함께 쓰이기 위한 API design
    그 외는 primary constructor with default argument 또는 DSL 사용이 권장된다.

 

 

Summary

#
Object 생성은 primary constructor 를 통하는 것이 대부분 가장 적합하다.
Telescoping constructor 는 Kotlin 에서 유효하지 않다.
Default value 를 사용하면 더 깔끔하고 유연하며 더 표현력 있다.
Builder 패턴은 Kotlin 세계에서는 잘 쓰이지 않으며, primary constructor with named argument 혹은 DSL 이 선호된다.

 

 

 

반응형

댓글0