Veröffentlicht am 19-02-2019

Hin und wieder zurück: Die Reise der GO-LIFE App

Lektionen im Refactoring eines Teams, das auf die harte Tour gelernt hat

superapp.jobs

Im November 2016 haben wir mit der Arbeit an der GO-LIFE-App begonnen. Seitdem wurden viele Änderungen an der Architektur, der Benutzeroberfläche und dem Ablauf der App vorgenommen. Zwei Jahre später sind wir bereit, unsere Erfahrungen zu teilen und zu vermitteln, was wir dabei gelernt haben.

Für Uneingeweihte ist GO-LIFE die On-Demand-Lifestyle-App von GOJEK. Wir bieten Massagen, Reinigungs-, Automobil-, Mechanik- und Schönheitsdienstleistungen für mehr als 1 Million Benutzer in 16 indonesischen Städten an. So sieht die App heute aus:

Abbildung 1: Die GO-LIFE-App

In diesem Blogbeitrag geht es um einige Fehler, die wir beim Erstellen der App gemacht haben, und was wir gelernt haben. Der große Imbiss für uns:

Beim Erstellen von Software geht es nicht nur um das Schreiben von Code. Es geht auch um die Menschen. Ein gutes Team verbessert das gesamte Ökosystem.
Architektur ist nur eine Metapher für Softwareentwicklung und insbesondere für den Teil der Software, der das ursprüngliche Produkt in dem Sinne liefert, in dem ein Architekt ein makelloses Gebäude liefert - Robert C. Martin
Abbildung 2. Die Code-Messung

Ich wette, Sie kennen Robert C. Martin und seine Lehren.

Tatsächlich ist die Codequalität nicht die einzige Messung in der obigen Formel. Wir messen unsere Codebasis unter Verwendung von 3Rs (Lesbarkeit, Lesbarkeit, Lesbarkeit). Während der Entwicklung stehen wir alle vor vielen Problemen. wie wir mit Parallelität, Transformation, Synchronisierung zwischen lokalen und Remote-Daten, benutzerdefinierten Ansichten, dynamischen Ansichten, Unveränderlichkeit und vielem mehr umgehen.

Jedes einzelne Problem hat seine eigene Lösung mit den richtigen Entwurfsmustern. Bevor wir weitergehen, lassen Sie mich unseren Entwicklungsprozess etwas erklären.

Abbildung 3. Entwicklungslebenszyklus

Erstellen - Messen - LernenDas muss jeder Softwareentwickler beachten. Wir sind keine Assistenten, und die Anwendungsentwicklung hat einen Zyklus.

  1. Build: Diese Phase unseres Entwicklungsprozesses umfasst den Produktdesign-Sprint zu einem Minimum realisierbaren Produkt (MVP). Dies endet mit einem Auslieferungsprototyp oder einer A / B-Testfunktion.
  2. Maßnahme: Wie der Name vermuten lässt, messen wir das Feedback der Nutzer, was funktioniert und was nicht. Dies basiert auf Ihrer ersten Hypothese.
  3. Erfahren Sie: Bewaffnet mit Benutzerfeedback, sollten Sie Ihre Hypothese verbessern.
Hören Sie immer auf Ihre Benutzer, um sie zu beschäftigen und Abwanderung zu vermeiden

Atmen Sie tief ein, wir sind auf dem Weg zum tiefen Ende.

Anwendungsdesign

In der Anfangsphase, was wir GO-LIFE v.1 nennen können, hatten wir nur vier Dienste, GO-MASSAGE, GO-AUTO, GO-GLAM und GO-CLEAN. Derzeit haben wir mehr als 8 Dienste.

Zu Beginn gab es nicht viele Gründe für den Benutzer, mehr Zeit mit der App zu verbringen. Der Fokus lag ganz auf dem Produkt; wie Sie den Benutzer dazu bringen können, mehr Aufträge auszuführen und mehr Aufträge auszuführen.

Heutzutage fügen wir Videos, Artikel, Gutscheine und weitere Funktionen hinzu, um Benutzer dazu zu bringen, tiefer in unser Angebot einzutauchen.

Dank unserer Forscher, Designer und PMs, die ständig daran arbeiten, die Benutzererfahrung zu verbessern und zu verbessern.
Abbildung 4: Transformation der Benutzeroberfläche

Anwendungsarchitektur

Im Entwicklungsprozess haben wir viele Änderungen vorgenommen, die sowohl Refaktoren als auch Umbauten umfassten. Es gibt bestimmte Gründe, warum wir das Design der Architektur ändern. Dies sind die wichtigsten:

  1. Funktionen hinzufügen und Fehler beheben
  2. Um das Design zu verbessern
  3. Optimieren Sie die Ressourcennutzung
  4. Performance

Die Verbesserung des Designs ohne Verhaltensänderung wird als Refactoring bezeichnet. Um dies zu erreichen, brauchen wir eine gute Architektur (ich erkläre das später). Dies bedeutet nicht, dass das Verhalten niemals geändert werden sollte, es hängt davon ab, was der Stakeholder benötigt.

Die Idee hinter Refactoring ist, dass wir die Anwendung wartungsfähiger, robuster, erweiterbarer und auch testbarer machen können.

Das Wichtigste beim Refactoring aus Änderungssicht ist, dass beim Refactor keine funktionalen Änderungen auftreten sollten (obwohl sich das Verhalten etwas ändern kann, da die strukturellen Änderungen, die Sie vornehmen, die Leistung zum Besseren oder Schlechteren verändern). ~ Michael Federn

In unserer ersten Entwicklung haben wir wie jede andere Anwendung mit einem Monolithen begonnen, das nur ein einziges App-Modul hatte. Zu dieser Zeit hatten wir nur fünf Ingenieure für Android (drei für die Consumer-App, zwei für die Mitra-App für Händler) und zwei für die iOS-Consumer-App. Alles war in Ordnung, wir haben pünktliche Veröffentlichungen geliefert und es gab keine größeren Abstürze, PMs waren glücklich, Stakeholder waren glücklich.

In den Sturm segeln

Alles änderte sich, als wir aufgefordert wurden, weitere Funktionen hinzuzufügen. Es blieb nicht genug Zeit, um entsprechende Testfälle hinzuzufügen, und die Albträume begannen. Das Ziel zur Veröffentlichung von GO-LIFE v3 war Mitte Dezember 2017. Es gab jedoch ein Problem.

Wir waren noch nicht fertig.

Die Zeitleiste war eng und unvermeidliche Änderungen in der Mitte des Sprints mischten sich mit einer weniger idealen Code-Architektur. Das Backend wurde nur zwei Wochen vor der Veröffentlichung fertiggestellt, unsere Codeabdeckung war nicht gut genug und Fragmente wurden nicht angemessen behandelt.

Am Ende benötigten wir sechs Patches für GO-LIFE Version 3.

Die Dinge mitten im Sprint zu ändern, war nicht ideal, aber auch die Ingenieure haben Fehler gemacht. Wir haben nicht alle Anwendungsfälle befriedigt, die wir hatten. Zum Beispiel haben wir in jedem API-Aufruf zwei Abschlüsse, einen Erfolg und einen Fehler. Fehlerausnahmen haben mehrere Typen, aber wir hatten keine geeigneten Handler für jeden. Dies führte dazu, dass bestimmte Fehlertypen zur Standardeinstellung wurden.

Sehen Sie sich den folgenden Code an (Dies ist ein aktuelles Implementierungsdetail, die Idee ist jedoch dieselbe wie bei der ursprünglichen Entwicklung)

Abbildung 5. Fehlerbehebung

Im Implementierungsdetail von networkError.getResponse haben wir eine Funktion höherer Ordnung verwendet, die einen nullfähigen Typ hat. Immer wenn wir die Schließung eines bestimmten Typs nicht explizit festlegen, wird diese Art von Funktion höherer Ordnung die Bedingung in networkError.getResponse nicht erfüllen und auf den Standardwert umleiten.

Es hat nicht geholfen, dass Testfälle manuell getestet wurden.

Oh, und diese Fragmente? Nicht jeder kannte den Lebenszyklus gut (Das Bild unten bereitet mir immer noch Kopfschmerzen).

Abbildung 6. Android LifeCycle
Hier ist ein vertrauter Absturz in Fabric

java.lang.IllegalStateException: Fragment nicht an Aktivität angehängt

Der Trick, um einen Absturz zu vermeiden, besteht in der Möglichkeit, „keine Aktivitäten zu bewahren“ und entsprechende Gerätetests und Abnahmetests zu haben, um die Fälle zu bearbeiten.

Das haben wir gelernt:

1. Verändere nichts mitten im Sprint.2. Für jedes Commit sollte ein geeigneter Test (sowohl Geräte- als auch Gerätetest) 3 vorliegen. Hilfe für automatisierte Tests.4. Ingenieure sollten gemeinsame Sitzungen durchführen, um das Wissen zu bereichern.

Abbildung 7. Ja! Absturzfreie Sitzungen

Wir werden einige der Methoden, die wir ausprobiert haben, besprechen, was funktioniert hat und was nicht. Wenn Sie dies für nützlich befunden haben, hinterlassen Sie Feedback in den Kommentaren und teilen Sie es mit anderen Entwicklern!

Bei GOJEK scheitern wir viel. Aber wir versäumen immer, aus unseren Fehlern zu lernen und die Dinge besser zu machen. Diese Denkweise hat dazu geführt, dass wir die weltweit größte App für die Bereitstellung von Lebensmitteln auf dem Einzelmarkt geworden sind und vom Call Center für Ojeks zu einer Super-App mit 18+ Produkten werden. Gehe hinüber zu gojek.jobs und begleite uns auf unserer epischen Reise

www.superapp.is

Siehe auch

5 Gründe, warum Sie noch nach London ziehen solltenAI & ArchitekturWarum Jupyter nicht mein ideales Notebook istMust-Have-Funktionen der Messaging-App