There are two places a business rule can be enforced in software. One is a check that runs when the customer taps the button. The other is the structure of the code itself, so that breaking the rule is something the compiler refuses to build. The first kind fails in production. The second fails at a desk.
A Closed List the Compiler Knows
Kotlin has a feature for declaring that a list of cases is complete. The documentation states the guarantee: "All direct subclasses of a sealed class are known at compile time. No other subclasses may appear outside the module and package within which the sealed class is defined" (Kotlin).
The value is what happens next quarter. An engineer adds a new payment method or a new order status. Every piece of code that has to handle the full list stops compiling until it deals with the new case. Nobody has to remember where those places are.
The Detail That Decides Whether It Works
That protection has a condition, and our own article skipped it until this month. The language documents the rule in two sentences: "If you use `when` as a statement, you don't need to cover all possible cases" and "If you use `when` as an expression, you must cover all possible cases" (Kotlin).
Written one way, the compiler guards the list. Written the other way, it may not. And a catch-all branch, added for convenience, switches the guard off entirely: the new case is quietly absorbed by the default. A team can believe it has this safety net and not have it.
More Than One Dimension
Real state is rarely one list. A screen is loading or loaded, online or offline, in sync or not. Since Kotlin 1.5.0 one type can belong to several closed lists at once, because "a class can directly inherit more than one sealed interface" (Kotlin). Each dimension is checked separately, and nobody writes a case for every combination.
What to Ask Your Team
- Which of our business rules are enforced by the compiler, and which by a runtime check?
- When we add a new status or product type, what tells us every place that must change?
- Do we allow catch-all branches over closed lists? A lint rule can forbid them.
-Rocky
#SoftwareQuality #Kotlin #DefectPrevention #EngineeringDreams #StrategiaX
Originally published on ANDROID-ARCHITECT, the Android engineering blog of Strategia-X, with the code.
