\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 \ac{bloc} wurden drei \acl{bloc} erstellt. Diese verwalten den den Anmeldezustand, den Inhalt des Warenkorbs sowie die verfügbaren Produkte. Die \ac{bloc}s 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 \ac{bloc}s 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<int>(
  stream: cartBloc.numberOfProductsStream,
  initialData: cartBloc.numberOfProducts,
  builder: (context, snapshot) {
    BenchmarkCounters.cartButton++;
    return ElevatedButton.icon(
      onPressed: () => 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 \ac{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 InheritedWidget lassen sich \ac{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 \ac{bloc} beispielsweise über den Konstruktor oder ein Dependency-Injection Tool übergeben werden.

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

\paragraph{\nameref{sec:testability}} Zur Testbarkeit von \ac{bloc} lässt sich Folgendes sagen. Die Geschäftslogik der einzelnen \ac{bloc} lässt sich gut testen, da das Flutter-Testing-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 \ac{bloc} Abhängigkeiten zu anderen \ac{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 \ac{bloc} zugreifen. Hierzu lässt sich sagen, dass das Ersetzen durch Platzhaltern ohne Probleme möglich war. Allerdings hängt dies auch von dem verwendeten Injection-System ab. In diesem Beispiel wurden InheritedWidgets 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 \ac{bloc} die Klasse dieses \ac{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.

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

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

\paragraph{\nameref{sec:readability}}

\paragraph{\nameref{sec:documentation}}

\paragraph{\nameref{sec:structure}}