TIL

아이템 39 태그 클래스보다는 클래스 계층을 사용하라

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 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 한정자

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>()
}

태그 클래스와 상태 패턴의 차이