Eine Woche des kompletten Umkrempelns geht zu Ende und unsere vier Hände gehen zur Siegerpose in die Luft: das ViewState-Konzept ist gerefactored! Lange haben wir mit wachsend skeptischem Blick der Code-Duplizierung zugesehen, wenn wir ein neues Feature angelegt haben. Dafür musste neben einem Fragment und ViewModel mindestens ein ViewStateUpdater, eine zugehörige Factory, Events und zugehörige Results und Methoden auf dem ViewModel, die lediglich Parameter durchgeschleift haben, angelegt werden. Das Coding dafür haben wir mangels einer besseren Lösung von Klasse zu Klasse kopiert und bei jedem Aufruf eines unserer Events hat mindestens einer von uns geflucht, dass man selbst diesen Aufruf, der doch eigentlich ganz einfach zu handhaben sein sollte, kopieren musste. Wir haben es lange aufgeschoben, weil wir genug Beispiele sammeln wollten, um eine für uns perfekte, allumfassende Lösung zu finden. Es hat zwei Tage gedauert, aber jetzt ist alles aufgeräumt und wir sind mit der Lösung mehr als zufrieden 🙂
Ein Event, meistens durchs UI getriggert, hatte bis jetzt immer ein zugehöriges Result, welches Werte gehalten hat, um den ViewState zu manipulieren. Die ViewStateUpdater haben sich dann um das Kopieren und Updaten des ViewStates gekümmert. Obwohl Events und Results beide im StateFlow untergebracht waren, fehlte trotzdem etwas der Zusammenhang. Das Einzige, was sie gemeinsam hatten war der Name. Jetzt haben wir alles in einer „Action“ verpackt. Hier kann in der Start-Methode bei länger laufenden Calls ein Flow zurück zu geben oder Daten, die wir im UI anzeigen wollen, gleich gecached werden, um damit den ViewState anzupassen. In einer weiteren Finish-Methode kopieren wir den ViewState und setzen die Properties, so wie sie im UI angezeigt werden sollen. Wir haben die Möglichkeit, auf Exceptions zu reagieren, eine Action aus einer Action heraus zu triggern und zu anderen Fragments zu navigieren. Die Funktionalität für jede Aktion eines Features ist jetzt an einer zentralen Stelle und unser Framework kümmert sich um die Abarbeitung. Man muss lediglich wissen, dass zum Ausführen einer Action „callAction“ aufgerufen werden muss und sonst nichts. Sweet.
Zwischen drinnen haben wir wie immer noch ein paar Dinge ins Framework umgezogen, wie z.B. ein initiales Update des ViewStates, damit die UI diesen nicht zu Beginn selbst triggern muss und wir haben uns mit Reflection in Kotlin beschäftigt, um die Copy-Methode unserer Data classes auf Instanzen aufrufen zu können, von deren Typ uns nur das Interface zur Verfügung stand. Und sicher noch eine Menge kleiner Sachen, die man gar nicht mehr alle aufzählen kann, aber die uns das Leben Woche für Woche einfacher machen und uns erlauben, Fahrt aufzunehmen. „Die Züge sind erforscht: Tut tut, wir kommen!“