It’s about separation of concerns. In particular, separating the stuff that can be in common KMPP code (the InputHandler) from the platform-specific stuff (the ViewModel base class and EventHandler). The Handlers don’t replace the ViewModel, they live inside one.
In Ballast, the ViewModel is really just a container for all your stuff, and is not where you are writing your business logic. This is important, because it allows you to use the same InputHandler on all KMPP platforms, and bridge the Ballast MVI code with that platform just by swapping out the ViewModel base class. This is similar to ReduxJS too, which has you configure a Store which is where your data lived, but beyond that, isn’t all that important by itself. The main functionality in Redux is in the Reducer functions.
In contrast, Orbit has you writing your code as functions within the ViewModel, but using the
= intent { }
syntax. This makes it harder to share the same implementation code on different platforms, since the ViewModel itself is tied to the platform. Orbit does have the same general idea as Ballast though, where you could define all your functions in a
ContainerHost
class and wrap that in a
ViewModel()
, which gives you that ability to write the MVI stuff in a platform-agnostic way. Ballast just makes this required, while it’s optional in Orbit.