<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\section{BLoC}
\label{eval:bloc}

\acl{bloc} sind ein weit verbreitetes Konzept zur Zustandsverwaltung. Die Grundlagen zu diesem Zustandsverwaltungssystem wurden bereits in \autoref{sec:bloc} eruiert.

\subsection{Implementierung}

Für die Implementierung der App mit BLoC wurden drei \acl{bloc} erstellt. Diese verwalten den Anmeldezustand, den Inhalt des Warenkorbs sowie die verfügbaren Produkte. Die BLoCs bestehen dabei aus zu teils mehreren \texttt{Stream}s und \texttt{Sink}s, die Zustandsänderungen von außen entgegennehmen und nach außen kommunizieren. Zusätzlich dazu gibt es für die \texttt{Stream}s öffentliche Variablen, welche den aktuellen Zustand wiedergeben. Dies dient, wie auch im Beispiel \autoref{lst:streambuilder} anhand des Parameters \texttt{initialData} zu sehen ist, dazu, dass Widgets, die erst später zum Widget-Tree hinzugefügt werden den aktuellen Zustand zum Zeitpunkt des initialen Erstellens erhalten können, da die Streams immer nur Zustandsänderungen kommunizieren können.

Alle drei BLoCs werden über ein Widget an die Benutzeroberfläche weitergegeben, welches als Dependency Injection fungiert. Hier wären auch andere Implementierungsvarianten beispielsweise mit dem Service Locator \texttt{get\_it} denkbar gewesen. Der gewählte Ansatz benötigt jedoch keine zusätzliche Bibliothek und verfälscht somit das Ergebnis am wenigsten. Die Widgets der Benutzeroberfläche verwenden dabei \texttt{StreamBuilder}, wie in \autoref{lst:streambuilder} zu sehen ist, um über aktualisierten Zuständen informiert zu werden.

\begin{lstlisting}[caption={Verwendung eines StreamBuilder in cart\_button.dart \cite{repo}}, label={lst:streambuilder}]
final cartBloc = AppState.of(context).blocProvider.cartBloc;
return StreamBuilder&lt;int&gt;(
  stream: cartBloc.numberOfProductsStream,
  initialData: cartBloc.numberOfProducts,
  builder: (context, snapshot) {
    BenchmarkCounters.cartButton++;
    return ElevatedButton.icon(
      onPressed: () =&gt; Navigator.of(context).pushRouteKey(RouteKey.cart),
      icon: const Icon(Icons.shopping_basket),
      label: Text('Warenkorb (${snapshot.requireData} Produkte)'),
    );
  },
);
\end{lstlisting}


\subsection{Bewertung}

Im folgenden Abschnitt wird die Implementierung mit BLoC \autocite[branch=\\bloc]{repo} anhand der definierten Bewertungskriterien bewertet.

\paragraph{\nameref*{sec:changeablility}}

Zu BLoC lässt sich sagen, dass diese sowohl skalierbar als auch änderbar sind. Diese Aussage stützt sich darauf, dass durch die Kommunikation ausschließlich über \texttt{Stream}s und \texttt{Sink}s sich eine einheitliche Schnittstelle schaffen lässt, an die beliege Komponenten sich andocken können. Anders als bei den Widget-basierten Ansätzen wie \texttt{Inherited\-Widget} lassen sich BLoC komplett plattformunabhängig einsetzen und sind somit für eine weitere Skalierung außerhalb des Flutter-Frameworks durchaus geeignet. 

Die Koppelung verschiedener Zustände lässt sich somit auch einfach lösen, indem andere BLoC beispielsweise über den Konstruktor oder ein Dependen\-cy-Injection Tool übergeben werden.

Aufgrund dieser Eigenschaften wird die Bewertung \textquote{vollständig erfüllt} vergeben.

\paragraph{\nameref*{sec:testability}} Zur Testbarkeit von BLoC lässt sich Folgendes sagen. Die Geschäftslogik der einzelnen BLoC lässt sich gut testen, da das Flutter-Test\-ing-Framework bereits Werkzeuge zum Überprüfen von Streams bereithält, wie sie im Test in \autoref{lst:testbloc} verwendet werden. Hier lassen sich somit auch einfach Unit-Tests verwenden. Falls BLoC Abhängigkeiten zu anderen BLoC oder Komponenten haben, müssen diese allerdings gemockt werden. Ohne eine entsprechende Bibliothek entstehen hier zusätzliche Aufwände durch das Implementieren von Mock-Klassen.

\begin{lstlisting}[caption={Test des Cart BLoC in cart\_bloc\_test.dart \cite{repo}}, label={lst:testbloc}]
test('test cart bloc', () async {
  const productBlocMock = ProductBlocMock();
  final cartBloc = CartBloc(productBlocMock);
  final expectedCart = {demoProducts.first: 1};
  expectLater(cartBloc.cartStream, emits(expectedCart));
  cartBloc.quantityEventSink.add(IncreaseQuantityEvent(demoProducts.first));
});
\end{lstlisting}

Ein weiterer betrachteter Aspekt beim Testen ist die Testbarkeit von Widgets, die auf BLoC zugreifen. Hierzu lässt sich sagen, dass das Ersetzen durch Platzhalter ohne Probleme möglich war. Allerdings hängt dies auch von dem verwendeten Injection-System ab. In diesem Beispiel wurden \texttt{Inherited\-Widgets} verwendet. Daher kann dies äquivalent zu dem dort beschriebenen Beobachtungen (vgl. \autoref{par:ihtesting}) gewertet werden. Zusätzlich dazu lässt sich sagen, dass für das Erzeugen eines Platzhalters (engl. mock) für ein BLoC die Klasse dieses BLoC vollständig gemockt werden muss. Hier lassen sich wie im vorhergehenden Absatz beschrieben, mehrere Strategien nutzen.

Aufgrund der einfachen Testbarkeit der Geschäftslogik sowie des möglichen Austausches mit Platzhaltern für Widget-Tests wird die Testbarkeit mit \textquote{vollständig erfüllt} bewertet.

\pagebreak
\paragraph{\nameref*{sec:efficiency}} Nach der Ausführung der Teststrecke ergaben die Zähler folgendes Ergebnis: 
\lstinputlisting[caption={Anzahl der Rendervorgänge bei BLoC}]{results/bloc/benchmarks.txt}

\paragraph{\nameref*{sec:complexity}} Die Auswertung der Metriken (vgl. \autoref{metrics:bloc}) ergab ein \ac{mi} von 82 für das gesamte Projekt.

\paragraph{\nameref*{sec:readability}} Die Verständlichkeit und Lesbarkeit bei BLoC wird anhand der in \autoref{sec:readability} beschriebenen Fragestellungen bewertet.

Zur Verwendung von BLoC ist es erforderlich, dass man sich mit Konzepten der asynchronen Programmierung beschäftigt, um die Funktionsweise von \texttt{Stream}s und \texttt{Sink}s verstehen zu können. Diese werden in der Flutter-Programmierung sonst selten benötigt. Daher ist davon auszugehen, dass Entwickler*innen diese erst lernen müssen.

Die Struktur der BLoC selber ist schwer nachvollziehbar, da die Kombination von Streams, Sinks und Variablen nicht auf den ersten Blick nachvollziehbar ist. Zudem sind die Schnittstellen zur Benutzeroberfläche nicht wie andere Schnittstellen den Sprachfluss angepasst, sondern werden bestimmt durch die jeweiligen Funktionen von \texttt{Stream}s und \texttt{Sink}s. Außerdem benötigt dieser Ansatz eine Großzahl von Klassen, um beispielsweise Argumente von Ereignissen und Zustände abbilden zu können. Dies erschwert zusätzlich die Lesbarkeit, wie auch von \citeauthor{experienceofdevelopingflutter} festgestellt wurde. \autocite[573]{experienceofdevelopingflutter}


Die tiefe Verschachtlung von Widgets kann bei BLoC nicht beobachtet werden, da hier nicht das Widget-System als Grundlage zum Einsatz kommt. Allerdings verlangt die Verwendung von \texttt{Stream}s den Einsatz von \texttt{Stream\-Builder}n in der Benutzeroberfläche, wie bereits in \autoref{lst:streambuilder} gezeigt wird. Dies gibt zwar auf der einen Seite große Kontrolle über die Verarbeitung von Zustandsänderungen, macht den Quelltext allerdings schwer lesbar, besonders bei der Verwendung von mehreren \texttt{StreamBuilder}n ineinander.

Zusammenfassend wird die Verständlichkeit und Lesbarkeit mit der Bewertung \textquote{nicht erfüllt} bewertet.

\paragraph{\nameref*{sec:documentation}} Die Dokumentation von BLoC ist schwierig zu bewerten, da es sich bei BLoC lediglich um ein Konzept handelt. Allerdings gibt es Bibliotheken, welche das Konzept mit Hilfs-Konstrukten versehen und so den Einsatz von BLoC einfacher machen. Die Dokumentation dieser Bibliotheken umfasst umfangreiche Erklärungen und Beispiele \autocite{blocLib}, die auch auf BLoC an sich übertragbar sind.

Zusätzlich bestehen eine große Anzahl an Artikeln und anderen Veröffentlichungen zum Thema BLoC.

Aufgrund der umfangreichen Dokumentation der beschriebenen Bibliothek und der Großzahl an Veröffentlichungen zu BLoC, wird die Dokumentation mit \textquote{vollständig erfüllt} bewertet.


\paragraph{\nameref*{sec:structure}} Zur Strukturbestimmung lässt sich sagen, dass BLoC strikte Vorgaben zur Konstruktion von BLoC macht, aber viele Aspekte wie die Injection in Widgets oder die Dependency Injection innerhalb der BLoCs unbeantwortet bleibt. Eine technische Forcierung der Struktur eines BLoC ist nur teilweise erkennbar, da die Verwendung von \texttt{StreamBuilder} die Existenz von \texttt{Stream}s voraussetzt. Weitere technische Forcierungen der Struktur sind auch mangels des Einsatzes einer Bibliothek nicht zu erkennen.

Daher wird die Strukturbestimmung mit \textquote{teilweise erfüllt} bewertet.</pre></body></html>