classEmptyList<T>() : ValueMatcher<T>() { overridefunmatch(value: T): Boolean = value is List<*> && value.isEmpty() }
classNotEmptyList<T>() : ValueMatcher<T>() { overridefunmatch(value: T): Boolean = value is List<*> && value.isNotEmpty() } }
sealed 한정자
sealed 한정자를 반드시 사용해야 하는 것은 아니다. 대신 abstract 한정자를 사용할 수도 있지만 sealed 한정자는 외부 파일에서 서브클래스를 만드는 행위 자체를 모두 제한한다.
sealed class 의 장점
외부에서 추가적인 서브클래스를 만들 수 없으므로 타입이 추가되지 않는 것이 보장된다. 따라서 when을 사용할 때 else 브랜치를 만들 필요가 없다.
위 장점을 이용해 새로운 기능을 쉽게 추가할 수 있으며 when 구문에서 처리하는 것을 잊어버리지 않을 수 있다.
1 2 3 4 5 6 7
fun<T> ValueMatcher<T>.reversed(): ValueMatcher<T> = when (this) { is ValueMatcher.EmptyList -> ValueMatcher.EmptyList<T>() is ValueMatcher.NotEmptyList -> ValueMatcher.NotEmptyList<T>() is ValueMatcher.Equal -> ValueMatcher.Equal<T>(value) is ValueMatcher.NotEqual -> ValueMatcher.NotEqual<T>(value) }
클래스의 서브 클래스를 제어하려면 sealed 한정자를 사용하고 abstract는 상속과 관련된 설계를 할 때 사용한다.
태그 클래스와 상태 패턴의 차이
태그 클래스와 상태 패턴(state pattern)을 혼동하면 안된다. 상태 패턴은 객체의 내부 상태가 변화할 때, 객체의 동작이 변하는 소프트웨어 디자인 패턴이다.