In diesem Artikel möchte ich einen Ansatz zum Aufteilen von Aufgaben in Unteraufgaben bei Verwendung von Clean Architecture betrachten.
Das Zerlegungsproblem wurde vom mobilen Entwicklungsteam von NullGravity festgestellt und unten, wie wir es gelöst haben und was am Ende passiert ist.

Hintergrund
Es war Herbst 2018, wir entwickelten die nächste Anwendung für einen Telekommunikationsbetreiber. Aber diesmal war es anders. Die Bedingungen waren ziemlich eng und an die Marketingkampagne des Kunden gebunden. Das Android-Team ist von 3 auf 6-7 Entwickler angewachsen. Im Sprint wurden mehrere Aufgaben übernommen und die Frage war, wie man sie effektiv zerlegt.
Was meinen wir, wenn wir effektiv sprechen:
- Die maximale Anzahl paralleler Aufgaben.
Dies ermöglicht es, alle verfügbaren Ressourcen zu belegen. - Reduzieren der Größe von Zusammenführungsanforderungen.
Sie werden nicht für die Show angesehen, und Sie können potenzielle Probleme bereits in der Phase der Codeüberprüfung erkennen. - Reduzieren Sie die Anzahl der Zusammenführungskonflikte.
Aufgaben werden schneller ausgeführt und es ist nicht erforderlich, den Entwickler auf Konfliktlösung umzustellen. - Eine Gelegenheit, Statistiken über Zeitkosten zu sammeln.
- Automatisieren Sie die Aufgabenerstellung in Jira.
Wie haben wir das Problem gelöst?
Wir unterteilen alle Unteraufgaben in folgende Typen:
- Daten
- Domain
- Leer
- Benutzeroberfläche
- Artikel
- Benutzerdefiniert
- Integration
Daten und Domäne entsprechen Ebenen in Clean Architecture.
Leer, Benutzeroberfläche, Element und Benutzerdefiniert beziehen sich auf die Präsentationsebene.
Die Integration gilt sowohl für die Domänen- als auch für die Präsentationsebene.
Abbildung 1. Position der Aufgaben in Bezug auf Clean Architecture-EbenenSchauen wir uns jeden Typ einzeln an.
Daten
Beschreibung von DTO, API, Arbeit mit Datenbank, Datenquelle usw.
Domain
Repository-Schnittstelle, Beschreibung von Geschäftsmodellen, Interaktoren.
Die Repository-Schnittstelle in der Datenschicht ist ebenfalls implementiert.
Eine auf den ersten Blick etwas unlogische Trennung ermöglichte es, Aufgaben der Daten- und Domänentypen so weit wie möglich zu isolieren.
Benutzeroberfläche
Erstellen eines grundlegenden Bildschirmlayouts und ggf. zusätzlicher Status.
Artikel
Wenn der Bildschirm eine Liste von Elementen ist, müssen Sie für jeden Typ ein Modell erstellen - Element. Um Item dem Layout zuzuordnen, benötigen Sie AdapterDelegate. Wir verwenden das
Delegatenadapterkonzept , jedoch mit einigen
Änderungen .
Erstellen Sie als Nächstes ein Beispiel für die Arbeit mit einem Listenelement in PresentationModel.
Leer
Basisklassen für Aufgaben wie UI oder Item erforderlich: PresentationModel, Framgent, Layout, DI-Modul, AdapterDelagate Factory. Bindungsschnittstellen und Implementierungen. Erstellen Sie einen Einstiegspunkt auf dem Bildschirm.
Das Ergebnis der Aufgabe ist der Anwendungsbildschirm. Es enthält Symbolleiste, RecyclerView, ProgressView usw. Das heißt, gemeinsame Schnittstellenelemente, deren Hinzufügung von verschiedenen Entwicklern dupliziert werden könnte und zu unvermeidlichen Zusammenführungskonflikten führen würde.
Benutzerdefiniert
Implementierung einer nicht standardmäßigen UI-Komponente.
Ein zusätzlicher Typ wird benötigt, um die Entwicklung einer neuen Komponente von einer Aufgabe vom Typ UI zu trennen.
Integration
Integration von Domain- und Präsentationsebenen.
Dies ist in der Regel eine der zeitaufwändigsten Aufgaben. Es ist notwendig, die beiden Ebenen zu reduzieren und die Punkte zu verfeinern, die in den vorherigen Phasen möglicherweise übersehen wurden.
Aufgabenreihenfolge
Aufgaben wie Daten, leer und benutzerdefiniert können sofort nach dem Start des Sprints gestartet werden. Sie sind unabhängig von anderen Aufgaben.
Die Domänenaufgabe wird nach der Datenaufgabe ausgeführt.
Die UI- und Item-Aufgaben nach der leeren Aufgabe.
Die Integrationsaufgabe ist die letzte, die abgeschlossen werden muss, da alle vorherigen Aufgaben abgeschlossen werden müssen.
Abbildung 2. Ausführung der Timeline-AufgabeTrotz der Tatsache, dass einige Aufgaben durch andere Aufgaben blockiert werden, können sie gleichzeitig oder mit einer leichten Verzögerung gestartet werden. Zu diesen Aufgaben gehören Domäne, Benutzeroberfläche und Element. Dadurch wird der Entwicklungsprozess beschleunigt.
Abbildung 3. Zeitleiste für die Ausführung von Aufgaben mit SperrenFür jede spezifische Funktionalität können die Aufgaben variieren.
Es kann eine andere Anzahl von leeren Aufgaben, Benutzeroberflächen, Elementen und Integrationen geben, und einige Typen fehlen möglicherweise einfach.
Prozessautomatisierung und Statistiksammlung
Um beim Erstellen einer Aufgabe Statistiken zu erfassen, wird ihr eine Bezeichnung zugewiesen. Mit diesem Mechanismus können Sie in Zukunft die für jeden Typ aufgewendete Zeit analysieren und die durchschnittlichen Kosten ermitteln. Die gesammelten Informationen können bei der Bewertung eines neuen Projekts angewendet werden.
Für die Automatisierung haben wir auch eine Lösung gefunden. Da Aufgaben typisch sind, sollte ihre Beschreibung in Jira anders sein. Wir haben Vorlagen zur Zusammenfassung und Beschreibung entwickelt. Zuerst war es nur eine JSON-Datei, der Python-Parser dieser Datei, und die Jira REST-API wurde verbunden, um Aufgaben zu generieren.
In dieser Form dauerte das Drehbuch fast ein Jahr. Heute hat es sich zu einer vollwertigen Desktop-Anwendung entwickelt, die in Python unter Verwendung der PyQt- und MVP-Architektur geschrieben wurde.
Vielleicht war MVP Overhead, aber als die erste Version von Tkinter unter MacOS Version 10.14.6 abstürzte und nicht alle Teams die Anwendung verwenden konnten, haben wir die Ansicht für PyQt in einem halben Tag problemlos umgeschrieben und es hat funktioniert. Wir waren erneut davon überzeugt, dass die Verwendung architektonischer Ansätze auch für solch einfache Aufgaben Vorteile hat. Ein Screenshot des JiraSubTaskCreator ist in Abbildung 4 dargestellt.
Abbildung 4. Der Hauptbildschirm von JiraSubTaskCreatorSchlussfolgerungen
- Wir haben einen Ansatz zur Zerlegung von Aufgaben in Teilaufgaben entwickelt, die nur minimal voneinander abhängig sind.
- Generierte Vorlagen zur Beschreibung von Aufgaben;
- Wir haben kleine Zusammenführungsanfragen erhalten, die es ermöglichen, den Code sorgfältig zu überprüfen und isoliert zu ändern
- Die Anzahl der Konflikte mit Zusammenführungsanforderungen wurde verringert.
- Wir hatten die Möglichkeit, die für jede Art von Aufgabe aufgewendete Zeit genauer einzuschätzen und zu analysieren.
- Automatisierter Teil der Routinearbeit.