You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
518 lines
19 KiB
518 lines
19 KiB
\documentclass[aspectratio=169]{beamer}
|
|
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[T1]{fontenc}
|
|
\usepackage{microtype}
|
|
|
|
\usepackage[ngerman]{babel}
|
|
\usepackage{tabularx}
|
|
\usepackage{graphicx}
|
|
\usepackage{transparent}
|
|
\usepackage{csquotes}
|
|
\usepackage{graphicx}
|
|
\usepackage{subfig}
|
|
\usepackage{tikz}
|
|
\usepackage{subfig}
|
|
\usepackage{longtable}
|
|
\usepackage{adjustbox}
|
|
\usepackage{array}
|
|
\usepackage{xparse} % http://ctan.org/pkg/xparse
|
|
\NewDocumentCommand{\rot}{O{45} O{1em} m}{\makebox[#2][l]{\rotatebox{#1}{#3}}}%
|
|
|
|
\usepackage{beamerthemesplit}
|
|
\usepackage{amssymb}% http://ctan.org/pkg/amssymb
|
|
\usepackage{pifont}% http://ctan.org/pkg/pifont
|
|
|
|
\newcommand{\backupbegin}{
|
|
\newcounter{finalframe}
|
|
\setcounter{finalframe}{\value{framenumber}}
|
|
}
|
|
\newcommand{\backupend}{
|
|
\setcounter{framenumber}{\value{finalframe}}
|
|
}
|
|
|
|
|
|
\usepackage[beamer,customcolors]{hf-tikz}
|
|
\tikzset{hl/.style={
|
|
set fill color=red!80!black!40,
|
|
set border color=red!80!black,
|
|
},
|
|
}
|
|
|
|
\usepackage[natbib=true,style=alphabetic,dateabbrev=false]{biblatex}
|
|
\usepackage{booktabs}
|
|
|
|
\addbibresource{../bibliography.bib}
|
|
\usetikzlibrary{positioning}
|
|
\usetikzlibrary{matrix}
|
|
\usetikzlibrary{arrows}
|
|
\usetikzlibrary{fit}
|
|
\usetheme{metropolis}
|
|
|
|
\title{Evaluation von Zustandsverwaltungssystemen für das mobile Cross-Plattform-Framework Flutter}
|
|
\subtitle{Kolloquium}
|
|
\date{22.~April~2022}
|
|
|
|
\author{Jonas Franz}
|
|
\institute{Hochschule Darmstadt -- Fachbereich Informatik\\Kooperativer Studiengang Informatik\\Referent: Prof. Dr. Kai Renz\\Koreferent: Prof. Dr. Hans-Peter Wiedling}
|
|
|
|
\begin{document}
|
|
|
|
\maketitle
|
|
\section{Einführung}
|
|
\begin{frame}{Ziel der Arbeit}
|
|
\begin{itemize}
|
|
\item Die Zustandsverwaltung ist ein entscheidender Aspekt einer Flutter-Anwendung
|
|
\item Fragestellung: Wie lässt sich der Zustand einer Flutter-Anwendung am besten verwalten?
|
|
\item Welcher Lösungsansatz ist am beste für verschiedene Anwendungsfälle geeignet?
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Vorgehen}
|
|
\begin{enumerate}
|
|
\item Recherche zu bestehenden Zustandsverwaltungssystemen
|
|
\item Konstruktion von Anforderungen
|
|
\item Ableitung von Bewertungskriterien
|
|
\item Erstellung eines Versuchsaufbaus
|
|
\item Durchführung und Bewertung
|
|
\end{enumerate}
|
|
\end{frame}
|
|
|
|
\section{Grundlagen}
|
|
\begin{frame}{Grundlagen}
|
|
\begin{itemize}
|
|
\item Was ist die Aufgabe der Zustandsverwaltung in Flutter?
|
|
\item Was ist Flutter?
|
|
\item Wie funktioniert Flutter?
|
|
\item Welche Zustandsverwaltungssystem werden evaluiert?
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}{Aufgabe der Zustandsverwaltung}
|
|
\foreignblockcquote{american}[Kap.8.1.2]{flutterInAction}{State management is a combination of passing data around the app, but also re-rendering pieces of your app at the right time.}
|
|
|
|
\foreignblockcquote{american}[Kap.1]{managingStateInFlutter}{State management is simply a technique, or multiple techniques, used to take care of the changes that occur in your application.}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Aufgabe der Zustandsverwaltung}
|
|
\begin{itemize}
|
|
\item Verwaltung von Änderungen in der App
|
|
\item Neu Rendern von Widgets zur richtigen Zeit
|
|
\item Verteilung von Daten innerhalb der App
|
|
\item Aufteilung in verschieden Zustandsebenen \autocite{appState}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Was ist Flutter?}
|
|
\begin{itemize}
|
|
\item Flutter ist ein Cross-Plattform-Framework zur Entwicklung von Anwendungen für diverse Plattformen wie iOS und Android \autocite{flutterSupportedPlatforms}
|
|
\item Ein Quelltext-Basis für alle Plattformen
|
|
\item Ziel: Reduzierung des Aufwands bei der Entwicklung
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Wie funktioniert Flutter?}
|
|
\begin{columns}[onlytextwidth,T]
|
|
\column{\dimexpr\linewidth-50mm-3mm}
|
|
\begin{itemize}
|
|
\item Flutter ist ein deklaratives UI-Toolkit
|
|
\item $\Rightarrow$ Es wird nur eine \textquote{Bauanleitung} für verschiedene Zustände definiert
|
|
\item Die Benutzeroberfläche wird anhand von sogenannten Widgets zusammengesetzt
|
|
\item $\Rightarrow$ Es entsteht eine Baumstruktur aus verschiedenen Widgets
|
|
\end{itemize}
|
|
\column{50mm}
|
|
\begin{figure}
|
|
\includegraphics[width=50mm]{../chapters/basics/flutter_tree.png}
|
|
\caption{Flutter Widget-Tree (eigene Darstellung)}
|
|
\end{figure}
|
|
\end{columns}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Widgets in Flutter}
|
|
\begin{itemize}
|
|
\item \textcquote[Kap.1.9]{flutterInAction}{Everything is a widget}
|
|
\item \texttt{StatelessWidget}
|
|
\begin{itemize}
|
|
\item kein eigener Zustand
|
|
\item Zustand wird über Konstruktorparameter übergeben
|
|
\end{itemize}
|
|
\item \texttt{StatefulWidget}
|
|
\begin{itemize}
|
|
\item Verwaltet eigenen Zustand
|
|
\item kann eigenen Zustand selbstständig verändern
|
|
\end{itemize}
|
|
\item \texttt{InheritedWidget}
|
|
\begin{itemize}
|
|
\item andere Widgets können auf den Zustand zugreifen
|
|
\item zugreifende Widgets ändern sich, falls sich der Zustand
|
|
\item eigener Zustand kann nicht selbstständig verändert werden
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Zustandsverwaltungssysteme}
|
|
\begin{itemize}
|
|
\item Mitgelieferte Werkzeuge:
|
|
\begin{itemize}
|
|
\item setState
|
|
\item InheritedWidget
|
|
\end{itemize}
|
|
\item Pattern:
|
|
\begin{itemize}
|
|
\item Business Logic Components (BLoC)
|
|
\end{itemize}
|
|
\item Bibliotheken aufbauend auf dem Provider-Prinzip
|
|
\begin{itemize}
|
|
\item Provider
|
|
\item Riverpod
|
|
\end{itemize}
|
|
\item Ansätze aus dem React-Ökosystem
|
|
\begin{itemize}
|
|
\item Redux
|
|
\item MobX
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\section{Bewertungskriterien}
|
|
\begin{frame}{Anforderungen und Metriken}
|
|
\begin{table}
|
|
\centering
|
|
\begin{tabular}{c|c}
|
|
|
|
\hline
|
|
\textbf{Anforderung} & \textbf{Metrik} \\
|
|
\hline
|
|
\hline
|
|
Änderbarkeit / Skalierbarkeit & qualitativ \\
|
|
\hline
|
|
Testbarkeit & qualitativ \\
|
|
\hline
|
|
Effizienz & Anzahl der Neubauten \\
|
|
\hline
|
|
Komplexität / Wartbarkeit & Maintainability-Index \\
|
|
\hline
|
|
Verständlichkeit / Lesbarkeit & qualitativ\\
|
|
\hline
|
|
Dokumentierung & qualitativ \\
|
|
\hline
|
|
Strukturbestimmung & qualitativ\\
|
|
\end{tabular}
|
|
\end{table}
|
|
\end{frame}
|
|
\section{Versuchsaufbau}
|
|
\begin{frame}{Versuchsaufbau}
|
|
\begin{itemize}
|
|
\item Implementierung einer Beispiel-Anwendung
|
|
\item Ziel: Grundlage für die Evaluation anhand der Bewertungskriterien
|
|
\item Maintainability Index wird automatisiert erfasst
|
|
\item Die Effizienz wird über eine automatisierte Teststrecke gemessen
|
|
\begin{itemize}
|
|
\item zwei Messstellen: Warenkorb-Button und Anmeldeschalter
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Beispielanwendung}
|
|
\begin{figure}[h]%
|
|
\centering
|
|
\subfloat[\centering Produktliste]{{\includegraphics[width=.2\linewidth]{../chapters/realisation/product_list.png} }}%
|
|
\qquad
|
|
\subfloat[\centering Warenkorb]{{\includegraphics[width=.2\linewidth]{../chapters/realisation/cart.png} }}%
|
|
\caption{Umsetzung der Wireframes in Flutter unter iOS}%
|
|
\label{fig:realisation}%
|
|
\end{figure}
|
|
|
|
\end{frame}
|
|
\section{Ergebnisse}
|
|
\begin{frame}
|
|
|
|
\newcommand{\cmark}{\ding{51}}%
|
|
\newcommand{\xmark}{\ding{55}}%
|
|
\begin{longtable}[]{@{}l|ccccccc@{}}
|
|
Zustandsverwaltung & \rot{Änderbarkeit/Skalierbarkeit} & \rot{Testbarkeit} &
|
|
\rot{Effizienz} & \rot{Komplexität/Wartbarkeit} & \rot{Verständlichkeit/Lesbarkeit} &
|
|
\rot{Dokumentierung} & \rot{Strukturbestimmung} \\
|
|
\midrule
|
|
\endhead
|
|
ohne Zustandsverwaltung & n. a. & n. a. & 1;2 & 83 & n. a. & n. a. & n.a. \\
|
|
\tikzmarkin<2>[hl]{a}setState & \multicolumn{7}{c}{nicht umsetzbar}\tikzmarkend{a} \\
|
|
Inherited\-Widget & / & \tikzmarkin<4>[hl]{c}/\tikzmarkend{c} & 8;6 & 83 & \tikzmarkin<3-4,7>[hl]{b}\xmark\tikzmarkend{b} & / & \xmark \\
|
|
BLoC & \cmark & \cmark & 8;4 & 82 & \tikzmarkin<5-6>[hl]{d}\xmark\tikzmarkend{d} & \cmark & \tikzmarkin<6>[hl]{e}/\tikzmarkend{e} \\
|
|
Provider & \tikzmarkin<8>[hl]{g}/\tikzmarkend{g} & \cmark & 3;4 & 83 & \tikzmarkin<7>[hl]{f}/\tikzmarkend{f} & \cmark & \xmark \\
|
|
Riverpod & \tikzmarkin<8>[hl]{h}\cmark\tikzmarkend{h} & \cmark & 3;4 & 80 & \cmark & \cmark & \xmark \\
|
|
Redux & \tikzmarkin<9-10>[hl]{i}\xmark\tikzmarkend{i} & / & 8;10 & 82 & / & \cmark & \tikzmarkin<10>[hl]{j}\cmark\tikzmarkend{j} \\
|
|
MobX & \tikzmarkin<11>[hl]{k}\cmark\tikzmarkend{k} & \cmark & 4;4 & 83 & \cmark & \cmark & / \\
|
|
\end{longtable}
|
|
|
|
|
|
\end{frame}
|
|
|
|
\section{Fazit}
|
|
\begin{frame}{Zusammenfassung}
|
|
\begin{itemize}
|
|
\item Fast alle Systeme konnten evaluiert werden
|
|
\item Metriken waren größtenteils aufschlussreich
|
|
\item Riverpod und MobX haben die besten Bewertungen erzielt
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Empfehlungen}
|
|
\begin{itemize}
|
|
\item Große Anwendungen: MobX
|
|
\item Mittelgroße Anwendungen: Riverpod
|
|
\item Kleine Anwendungen: InheritedWidget / Provider
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}[noframenumbering,plain,allowframebreaks]{Quellen}
|
|
\AtNextBibliography{\tiny}
|
|
\printbibliography[heading=none]
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
|
|
\backupbegin
|
|
\appendix
|
|
\begin{frame}{Änderbarkeit / Skalierbarkeit}
|
|
\begin{itemize}
|
|
\item Umgang mit wachsender Größe von Zuständen
|
|
\item Effektive Vernüpfung verschiedener Zustände
|
|
\item Metrik: qualitativ (nicht-/teilweise-/vollständig erfüllt)
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Testbarkeit}
|
|
\begin{itemize}
|
|
\item Testbarkeit der Geschäftslogik
|
|
\item Widget-Tests von Widgets, die auf Zustände zugreifen
|
|
\item Metrik: qualitativ (nicht-/teilweise-/vollständig erfüllt)
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Effizienz}
|
|
\begin{itemize}
|
|
\item Wie effizient orchestriert das System das Neubauen von Widgets?
|
|
\item Einbau von Prüfstellen
|
|
\item Zählen der Widget-Neubauten an den Prüfstellen
|
|
\item Metrik: Anzahl der Neubauten (kleiner ist besser)
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Komplexität / Wartbarkeit}
|
|
\begin{itemize}
|
|
\item Messung anhand von Quelltext-Metriken
|
|
\item Verwendung des Maintainability-Index
|
|
\item Kombiniert verschiedene Metriken \autocite[133]{mi}
|
|
\begin{itemize}
|
|
\item Halstead-Volumen
|
|
\item Zyklomatische Komplexität
|
|
\item Anzahl der Quelltextzeilen
|
|
\end{itemize}
|
|
\item Ergebnis wird auf eine Skala von 0 bis 100 abgebildet (größer ist besser)
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Verständlichkeit / Lesbarkeit}
|
|
\begin{itemize}
|
|
\item Werden neue Flutter-fremde Konzepte eingeführt?
|
|
\item Gibt es eine nachvollziehbare Struktur?
|
|
\item Wird der tiefen Verschachtelung von Widgets entgegengewirkt? (Nesting)
|
|
\item Metrik: qualitativ (nicht-/teilweise-/vollständig erfüllt)
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Dokumentierung}
|
|
\begin{itemize}
|
|
\item Gibt es eine Entwickler*innen-Dokumentation?
|
|
\item Werden die Grundkonzepte erläutert?
|
|
\item Gibt es umfangreiche Beispiele?
|
|
\item Metrik: qualitativ (nicht-/teilweise-/vollständig erfüllt)
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Strukturbestimmung}
|
|
\begin{itemize}
|
|
\item Macht das System Vorgaben an die Struktur / Architektur der Anwendung?
|
|
\item Werden diese technisch forciert?
|
|
\item Metrik: qualitativ (nicht-/teilweise-/vollständig erfüllt)
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{setState}
|
|
\begin{itemize}
|
|
\item Verwendung des \texttt{StatefulWidget} zum Speichern des Zustands
|
|
\item Umsetzung der Beispielanwendung war nicht möglich, da ein Zustand nicht über mehrere Seiten hinweg konsistent gehalten werden konnte
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{InheritedWidget}
|
|
\begin{itemize}
|
|
\item Verwendung des \texttt{InheritedWidget} zum Speichern des Zustands
|
|
\item Verwendung von \texttt{StatefulWidget}s zum aktualiseren des \texttt{InheritedWidget}
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Ergebnisse: InheritedWidget}
|
|
\begin{table}
|
|
\centering
|
|
\begin{tabular}{cc}
|
|
\hline
|
|
Metrik & Ergebnis \\
|
|
\hline
|
|
Änderbarkeit/Skalierbarkeit & teilweise erfüllt \\
|
|
Testbarkeit & teilweise erfüllt \\
|
|
Effizienz & Warenkorb-Button: 8; Anmeldeschalter: 6 \\
|
|
Komplexität/Wartbarkeit & 83 \\
|
|
Verständlichkeit/Lesbarkeit & nicht erfüllt \\
|
|
Dokumentierung & teilweise erfüllt \\
|
|
Strukturbestimmung & nicht erfüllt\\
|
|
\hline
|
|
\end{tabular}
|
|
\end{table}
|
|
\end{frame}
|
|
\begin{frame}{Business Logic Components (BLoC)}
|
|
\begin{itemize}
|
|
\item Komplette Trennung von Geschäftslogik und Benutzeroberfläche \autocite[17]{Faust}
|
|
\item Änderungen und Lesen eines Zustands nur über Streams und Sinks
|
|
\item Keine Abhängigkeiten zur Benutzeroberfläche
|
|
\item Kein Plattformabhängiger Quelltext in den Zuständen (BLoCs) \autocite{blocTalk}
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Ergebnisse: BLoC}
|
|
\begin{table}
|
|
\centering
|
|
\begin{tabular}{cc}
|
|
\hline
|
|
Metrik & Ergebnis \\
|
|
\hline
|
|
Änderbarkeit/Skalierbarkeit & vollständig erfüllt \\
|
|
Testbarkeit & vollständig erfüllt \\
|
|
Effizienz & Warenkorb-Button: 8; Anmeldeschalter: 4 \\
|
|
Komplexität/Wartbarkeit & 82 \\
|
|
Verständlichkeit/Lesbarkeit & nicht erfüllt \\
|
|
Dokumentierung & vollständig erfüllt \\
|
|
Strukturbestimmung & teilweise erfüllt\\
|
|
\hline
|
|
\end{tabular}
|
|
\end{table}
|
|
\end{frame}
|
|
\begin{frame}{Provider}
|
|
\begin{itemize}
|
|
\item Bibliothek basierend auf InheritedWidgets
|
|
\item Nutzung von u.a. ChangeNotifier für Zustandsklassen \autocite{stateManagementThesis}
|
|
\item Vereinfachung der Erstellung und Benutzung von Zustandsklassen
|
|
\item Zugriff auf Zustände via Generic (z.B. \texttt{Provider.of<UserStore>(context)})
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Ergebnisse: Provider}
|
|
\begin{table}
|
|
\centering
|
|
\begin{tabular}{cc}
|
|
\hline
|
|
Metrik & Ergebnis \\
|
|
\hline
|
|
Änderbarkeit/Skalierbarkeit & teilweise erfüllt \\
|
|
Testbarkeit & vollständig erfüllt \\
|
|
Effizienz & Warenkorb-Button: 3; Anmeldeschalter: 4 \\
|
|
Komplexität/Wartbarkeit & 83 \\
|
|
Verständlichkeit/Lesbarkeit & teilweise erfüllt \\
|
|
Dokumentierung & vollständig erfüllt \\
|
|
Strukturbestimmung & nicht erfüllt\\
|
|
\hline
|
|
\end{tabular}
|
|
\end{table}
|
|
\end{frame}
|
|
\begin{frame}{Riverpod}
|
|
\begin{itemize}
|
|
\item Bibliothek erweitert den Provider-Ansatz
|
|
\item Einführung des StateNotifier für die Zustandsklassen
|
|
\begin{itemize}
|
|
\item Trennung von Zustandsdaten und Zustandslogik
|
|
\end{itemize}
|
|
\item Zugriff auf Zustände über globale Variablen
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{Ergebnisse: Riverpod}
|
|
\begin{table}
|
|
\centering
|
|
\begin{tabular}{cc}
|
|
\hline
|
|
Metrik & Ergebnis \\
|
|
\hline
|
|
Änderbarkeit/Skalierbarkeit & vollständig erfüllt \\
|
|
Testbarkeit & vollständig erfüllt \\
|
|
Effizienz & Warenkorb-Button: 3; Anmeldeschalter: 4 \\
|
|
Komplexität/Wartbarkeit & 80 \\
|
|
Verständlichkeit/Lesbarkeit & vollständig erfüllt \\
|
|
Dokumentierung & vollständig erfüllt \\
|
|
Strukturbestimmung & nicht erfüllt\\
|
|
\hline
|
|
\end{tabular}
|
|
\end{table}
|
|
\end{frame}
|
|
\begin{frame}{Redux}
|
|
\begin{itemize}
|
|
\item Ansatz stammt aus dem React-Ökosystem
|
|
\item Ein Zustand für die gesamte Anwendung
|
|
\item Der Gesamtzustand (Store) ist unveränderlich
|
|
\item Der Store kann nur durch Reducer ersetzt werden \autocite[Kap.1.3.2f]{redux}
|
|
\end{itemize}
|
|
|
|
\begin{figure}
|
|
\includegraphics[width=\textwidth]{../chapters/basics/reduxflow.jpg}
|
|
\caption{Datenfluss in Redux \autocite[Kap.1.3.3]{redux}}
|
|
\end{figure}
|
|
\end{frame}
|
|
\begin{frame}{Ergebnisse: Redux}
|
|
\begin{table}
|
|
\centering
|
|
\begin{tabular}{cc}
|
|
\hline
|
|
Metrik & Ergebnis \\
|
|
\hline
|
|
Änderbarkeit/Skalierbarkeit & nicht erfüllt \\
|
|
Testbarkeit & teilweise erfüllt \\
|
|
Effizienz & Warenkorb-Button: 8; Anmeldeschalter: 10 \\
|
|
Komplexität/Wartbarkeit & 82 \\
|
|
Verständlichkeit/Lesbarkeit & teilweise erfüllt \\
|
|
Dokumentierung & vollständig erfüllt \\
|
|
Strukturbestimmung & vollständig erfüllt\\
|
|
\hline
|
|
\end{tabular}
|
|
\end{table}
|
|
\end{frame}
|
|
\begin{frame}{MobX}
|
|
\begin{itemize}
|
|
\item Ansatz stammt ebenfalls aus dem React-Ökosystem
|
|
\item Ziel: Vereinfachung von Ableitungen von Informationen aus dem Anwendungs-Zustand
|
|
\end{itemize}
|
|
\end{frame}
|
|
\begin{frame}{MobX: Grundkonzepte}
|
|
\begin{columns}
|
|
\column{\dimexpr\linewidth-80mm-18mm}
|
|
\blockcquote[130]{mobx}{\begin{itemize}\item Observables [...]
|
|
\item Computed Values [...]
|
|
\item Reactions [...]
|
|
\item Actions [...]
|
|
\end{itemize}}
|
|
\column{80mm}
|
|
\begin{figure}
|
|
\includegraphics[width=80mm]{mobx.png}
|
|
\caption{Ablaufdiagramm \autocite{mobxDocs}}
|
|
\end{figure}
|
|
\end{columns}
|
|
\end{frame}
|
|
\begin{frame}{Ergebnisse: MobX}
|
|
\begin{table}
|
|
\centering
|
|
\begin{tabular}{cc}
|
|
\hline
|
|
Metrik & Ergebnis \\
|
|
\hline
|
|
Änderbarkeit/Skalierbarkeit & vollständig erfüllt \\
|
|
Testbarkeit & vollständig erfüllt \\
|
|
Effizienz & Warenkorb-Button: 4; Anmeldeschalter: 4 \\
|
|
Komplexität/Wartbarkeit & 83 \\
|
|
Verständlichkeit/Lesbarkeit & vollständig erfüllt \\
|
|
Dokumentierung & vollständig erfüllt \\
|
|
Strukturbestimmung & teilweise erfüllt\\
|
|
\hline
|
|
\end{tabular}
|
|
\end{table}
|
|
\end{frame}
|
|
\backupend
|
|
\end{document}
|
|
|
|
|