class ValueMatcher<T> private constructor(
private val value: T? = null,
private val matcher: Matcher
) {
enum class Matcher { EQUAL, NOT_EQUAL, LIST_EMPTY, LIST_NOT_EMPTY }
fun match(value: T?) = when (matcher) {
Matcher.EQUAL -> value == this.value
Matcher.NOT_EQUAL -> value != this.value
Matcher.LIST_EMPTY -> value is List<*> && value.isEmpty()
Matcher.LIST_NOT_EMPTY -> value is List<*> && value.isNotEmpty()
}
}
sealed
클래스를 많이 사용한다.
sealed class ValueMatcher<T> {
abstract fun match(target: T?): Boolean
class Equal<T>(private val value: T) : ValueMatcher<T> {
override fun match(target: T?): Boolean = target == value
}
class NotEqual<T>(private val value: T) : ValueMatcher<T> {
override fun match(target: T?): Boolean = target != value
}
class EmptyList<T> : ValueMatcher<T> {
override fun match(target: T?): Boolean = target is List<*> && target.isEmpty()
}
class NotEmptyList<T> : ValueMatcher<T> {
override fun match(target: T?): Boolean = target is List<*> && target.isNotEmpty()
}
}
sealed
한정자를 사용해야 하는 것은 아니지만 외부 파일에서 서브클래스를 만들게 하고 싶지 않다면 유용하다.
when
을 사용할 때 else
브랜치를 따로 만들 필요가 없어지고 when
구문에서 이를 처리하는 것을 잊지 않을 수 있다.when
은 모드를 구분해서 다른 처리를 만들 때 굉장히 편리하다.
when
을 활용한 확장함수로 한 번에 구현할 수 있다.fun <T> ValueMatcher<T>.reversed(): ValueMatcher<T> = when (this) {
is ValueMatcher.Equal -> ValueMatcher.NotEqual(value)
is ValueMatcher.NotEqual -> ValueMatcher.Equal(value)
is ValueMatcher.EmptyList -> ValueMatcher.NotEmptyList<T>()
is ValueMatcher.NotEmptyList -> ValueMatcher.EmptyList<T>()
}