Entwicklungseinblick #1

Entwicklungseinblick

Einblicke in meinen akuellen Entwicklungsstand in Sachen Entwicklung von Flutter Appliaktionen.

Vorwort

Googles Framework Flutter bietet die Möglichkeit, native Applikationen für verschiedene Betriebssysteme aufgrund der gleichen Code-Basis zu kompilieren. Also, ein Code für Android, iOS, Web, macOS, Windows… während es weiterhin möglich ist, pro Betriebssysteme zu separieren und Funktionalitäten platformabhängig einzubauen, was in Fällen von Nutzung hardware-naher Komponenten erforderlich sein kann, falls es noch kein geeignetes Package dafür gibt. pub.dev bietet eine Vielzahl solcher Packages und wird als standard Quelle für diese verwendet. Während der Quellcode in Dart geschrieben wird, können unterschiedliche Funktionalitöten der Systeme in der jeweiligen Programmiersprache geschrieben sein. Der Aufbau der Oberfläche ist ähnlich HTML durch Komponenten in einer baumartigen Struktur aufgebaut. Eins wird jedem Flutter Entwickler sehr früh bewusst:
everything is a widget

Weitere Informationen auf Flutter und Dart

Entwicklungsumgebung

Die Entwicklungsumgebung VSCode birgt eine Menge an Erweiterungen für viele Programmiersprachen und Systeme. So auch für Flutter. Sei es Starten der App mit verschienden Einstellungen, mit Emulator im Web oder direkt als Desktop Applikation, Ausführen von notwendigen Build Tasks, Verwaltung von verschiedenen Kommentar-Tags wie ToDo, Info oder beliebig weitere oder optische hervorhebung und veranschaulichung von Code, so gut wie alles ist über Tastenkürzel erreichbar. Einige der genannten Funktionen sind zwar erst durch Erweiterungen verfügbar, doch ist die Suche und Installation nach diesen über den Erweiterungsreiter sehr einfach zu bewerkstelligen. Im Netz findet man je nach Programmiersprache viele Artikel über verschiedene nützliche dieser Erweiterungen.

Versionsverwaltung

Entschieden für GitLab, das kostenlos auch private Projekte zulässt. Neben den herkömmlichen Git Funktionen ist mir die Continious Integration / Continious Delivery von besonderem Interesse. Mit dieser wird bspw. die Code-Coverage angehauen und per GitLab Badge in der README angezeigt. Tests können auch hier durchgeführt werden oder beliebig weitere Programme und Operationen, die das benutzte Image hergibt, ausgeführt werden.

CI/CD

Wie bereits beschrieben wird die Code-Coverage mit GitLab CI/CD erstellt. Nachdem ein Task erfolgreich durchgelaufen ist, wird CodeMagic angestoßen. Codemagic baut je nach Konfiguration die App für verschiedene Betriebssysteme und liefert sie ebenso abhängig davon aus. (Bsp. Google Playstore, iOS Appstore)
Dafür ist das Erstellen verschiedener Build-Konfigurationen möglich, deren Build durch verschiedene Ereignisse des Repositories automatisch gestartet werden können.

Datenspeicherung / -verwaltung

Als einfache Lösung zur Speicherung und Verwaltung von Daten wird Firebase genutzt. Mit der Firebase SDK für Flutter/Dart kann Firebase direkt im Code verwendet werden. Darüber können Daten nach definierbaren Regeln verändert werden, Authentifizierung vorgenommen werden, Benachrichtigungen in der App getriggert werden und dient als hosting Platform für eine Webversion einer App. Mit Erweiterungen lassen sich selbst Mails automatisiert verschicken. Firebase bietet noch mehr Funktionalitäten, von denen ich noch keinen Gebrauch gemacht habe.

Grundlegende Software-Architektur

Als Software-Architektur habe ich mich für ein Domain-Driven-Design entschieden.

Die Grundlegende Idee ist inspiriert durch Reso Coder DDD

DDD-Architekturvorschlag

In diesem Entwurf gibt es 4 verschiedene Ebene mit fließendem Übergang:

  • Präsentation
  • Applikation
  • Domäne
  • Infrastruktur

Am wichtigsten ist, dass die Domänen-Ebene keinerlei Abhängigkeiten aus den anderen Ebenen hat. Die Domänen-Ebene ist zuständig für die Entitäten, die in der Domäne verwendet werden, für Werte-Objekte, die validierbare Werte enthalten und herkömmlicherweise von den Entitäten genutzt werden, für die Deklaration zu implementierender Funktionalitäten, und für die Fehler, die im Prozess der Kommunikation mit der Infrastruktur auftreten können. Die Infrastruktur-Ebene stellt die Kommunikation mit System bereit, deren Funktionalität in der Domänen-Ebene vorgeschrieben werden. Dabei kann sowohl mit lokalen als auch externen Systemen kommuniziert werden und durch Vorgabe von Funktionalität der Domänen-Ebene modular ersetzt werden. Je nach Richtung der Kommunikation werden die Entitäten in extra angelegte Datenübertragungsobjekte umgewandelt oder durch diese erstellt. Auftretende Ausnahmen werden während dieses Vorganges in Fehler aus der Domänen-Ebene umgewandelt, um sie in darüber stehenden Ebenen wie der Applikations-Ebene zu verarbeiten. In der Applikations-Ebene wird nach der Abbildung BLoC als State Management Lösung verwendet. In meinen Projekten verwende ich stattdessen Riverpod. Zustände, die in der Oberfläche angezeigt oder festgehalten werden sollen, werden mit der State Management Lösung verwaltet. In der Abbildung dient die Applikations-Ebene um Use Cases zu handhaben. In der Umsetzung ist sie dafür zuständig, die Daten zwischen den darüber und darunter liegenden Ebenen zu Orchestrieren. Die Zustände und Ereignisse werden hier konträr zur Darstellung festgehalten und gehandhabt. Nur in der Präsentations-Ebene liegen vorzüglich Widgets, die dem Nutzer in der Oberfläche angezeigt werden. Der fließende Übergang von der Applikations-Ebene über die Zustände und Ereignisse zur Präsentations-Ebene bringt Daten aus der Infrastruktur-Ebene vertraglich abgesichert durch die Domänen-Ebene vom Nutzer zur Infrastruktur und auch andersherum.

Beispiele

https://gitlab.com/goevexx/flutter-js-card-trick (Enthält potentiell Antipatterns)

Blick nach vorne…

Demnächst halte ich Ausschau nach Anwendungsfällen für Apps, die auf dieser Zusammensetzung basieren, um sie zu verfeinern und zu verbessern. Des Weiteren stelle ich in Aussicht, mich von Firebase unabhängig zu machen, indem ich Serverseitige Anbindung und Verwaltung der Daten mit Anwendungen in Golang umsetze.

comments powered by Disqus