Verwalten des Anwendungsstatus in Flutter

Hallo Habr! Lassen Sie mich Ihnen helfen, eine State-Management-Lösung für Ihre App zu verstehen und auszuwählen , die mir aufgefallen ist und mich für den Prozess des Lernens der Grundlagen des State-Managements in Flutter interessiert hat. Ich freue mich über jede Kritik zu dieser Übersetzung. In Backquotes (``) werden meine persönlichen Gedanken und Erklärungen geschrieben.


Flatter State Management ist ein heißes Thema. Es gibt viele mögliche Lösungen für das Problem, und die Auswahl der für Ihre Bedürfnisse am besten geeigneten Lösung ist äußerst einfach. Ich selbst war verwirrt, fand aber eine geeignete Lösung. Lass es mich mit dir teilen.

Um eine Lösung zu finden, die Ihren Anforderungen entspricht, müssen Sie die Anforderungen selbst ermitteln. In meinem Fall ist dies:

  • Sie haben die Möglichkeit, das Projekt zu entwickeln, ohne die Qualität des Codes zu beeinträchtigen
  • Trennen Sie die Anzeigelogik von der Geschäftslogik
  • Haben Sie klaren Code, der schwer zu brechen ist
  • Vorhersehbarkeit und Verständlichkeit des Codes

Angesichts dieser Anforderungen bleiben geeignete Optionen:

  • Verwenden der setState() und Stateful Widgets
  • `Library` ScopedModel
  • Verwenden des BLoC-Musters (Business Logic-Komponenten)
  • Redux

Der Unterschied zwischen lokalem und globalem Zustand


Bevor Sie sich mit der Analyse ausgewählter Lösungen befassen, müssen Sie den Unterschied zwischen lokalem und globalem Zustand verstehen. Ein praktisches Beispiel ist dafür geeignet:
Stellen Sie sich ein Autorisierungsformular vor, in dem der Benutzer aufgefordert wird, einen Benutzernamen und ein Kennwort einzugeben und nach dem Senden des Formulars das Objekt "Benutzeridentität" abzurufen. In diesem Beispiel ist jede Überprüfung der in die Formularfelder eingegebenen Daten Teil des lokalen Status des "Autorisierungsformular-Widgets", und der Rest der Anwendung sollte dies nicht wissen. Das vom "Autorisierungsserver" zurückgegebene "Identitäts" -Objekt ist Teil des globalen Status. Andere Komponenten hängen also von diesem Objekt ab und ändern das Verhalten abhängig davon, ob der Benutzer autorisiert ist.

Kurze Schlussfolgerungen für diejenigen, die es satt haben zu warten
Wenn Sie nicht warten möchten oder nicht an meiner Forschung interessiert sind, finden Sie hier einen kurzen Überblick über die Ergebnisse:


Ich empfehle, BLoC für die lokale Statusverwaltung und Redux für den globalen Status zu verwenden, insbesondere wenn Sie eine komplexe Anwendung erstellen, die mit der Zeit wächst.


Warum sollten Sie setState () nicht verwenden?


Die Verwendung von setState() in Ihren Widgets ist setState() um schnell Prototypen zu setState() und Feedback zu diesen Änderungen zu erhalten. Auf diese Weise können wir unsere Ziele jedoch nicht erreichen, da die Anzeigelogik mit der Geschäftslogik gemischt wird, was gegen das Prinzip der Sauberkeit und Qualität des Codes verstößt. Die Wartung eines solchen Codes wird in Zukunft schwierig sein. Daher wird dieser Ansatz, abgesehen von der Erstellung von Prototypen, nicht empfohlen.

ScopedModel - ein Schritt in die richtige Richtung


ScopedModel ist eine Drittanbieter-Bibliothek von Brian Egan . Es ermöglicht das Erstellen spezieller Models Objekte sowie die Verwendung der notifyListeners() -Methode, notifyListeners() erforderlich. So verfolgen Sie beispielsweise Änderungen an den Eigenschaften eines Modellobjekts:

 class CounterModel extends Model { int _counter = 0; int get counter = _counter; void increment() { _counter++; notifyListeners(); } } 

In unseren Widgets können wir mit dem von dieser Bibliothek bereitgestellten ScopedModelDescendant Widget auf Änderungen im Modell reagieren:

 class CounterApp extends StatelessWidget { @override Widget build(BuildContext context) { return new ScopedModel<CounterModel>( model: new CounterModel(), child: new Column(children: [ new ScopedModelDescendant<CounterModel>( builder: (context, child, model) => new Text('${model.counter}'), ), new Text(" ,     CounterModel") ]) ); } } 

Im Gegensatz zur Verwendung des setState() -Ansatzes können Sie mit dieser Lösung die Anzeigelogik von der Geschäftslogik trennen. Es gibt jedoch bestimmte Einschränkungen:

  • Wenn das Model komplex wird, ist es schwierig zu bestimmen, wann die notifyListeners() -Methode verwendet werden soll und wann eine unnötige Schnittstellenaktualisierung nicht notifyListeners() werden soll.
  • Die von Model bereitgestellte API beschreibt im Allgemeinen die asynchrone Natur der Anwendungsschnittstelle nicht genau

In Anbetracht dessen empfehle ich die Verwendung dieses Datenansatzes nicht, wenn der Status Ihrer Anwendung nicht einfach zu verwalten ist. Ich glaube einfach nicht, dass er in der Lage ist, das Wachstum und die Komplexität von Anwendungen produktiv bereitzustellen.

Leistungsstarke Lösung - BLoC


Dieses Muster wurde von Google erfunden und wird auch dort verwendet. Er wird uns helfen, die folgenden Ziele zu erreichen:

  • Trennung der Anzeigelogik von der Geschäftslogik
  • Verwenden der asynchronen Natur zum Anzeigen einer Schnittstelle
  • Die Möglichkeit zur Wiederverwendung in verschiedenen Dart-Anwendungen wie Flutter oder AngularDart

Die Idee hinter diesem Ansatz ist sehr einfach:

  • BLoC verwendet
     Sink<T> 
    API zur asynchronen Eingabe unserer Datenkomponenten
  • BLoC verwendet
     Stream<T> 
    API zur Beschreibung der von unseren Komponenten asynchron zurückgegebenen Daten
  • Schließlich können wir das StreamBuilder Widget verwenden, um den StreamBuilder zu steuern, ohne StreamBuilder wir uns StreamBuilder zu abonnieren und Widgets neu zu zeichnen

Google hat gute Beispiele für die Verwendung dieses Zustandsverwaltungsmusters, da es weit verbreitet ist und vom Unternehmen dringend empfohlen wird.

Ich selbst empfehle dringend, diesen Ansatz zur Verwaltung des lokalen Zustands zu verwenden, aber er eignet sich sogar zur Verwaltung des globalen Zustands. Im letzteren Fall tritt jedoch ein Problem auf - wo und wie BLoC korrekt implementiert wird, damit verschiedene Komponenten darauf zugreifen können, und dann betritt Redux die Szene.

Redux und BLoC - die perfekte Mischung für mich


Eines der Ziele, die ich am Anfang des Artikels beschrieben habe, war es, etwas zu finden, das weit verbreitet und vorhersehbar ist, und dies ist Redux - ein Muster und eine Reihe von Werkzeugen, die uns zusammen helfen, den globalen Zustand zu verwalten. Es hat drei Grundprinzipien im Kern:

Die einzige Quelle der Wahrheit ist, dass der gesamte Status des state Ihrer Anwendung in einem Baumobjekt in einem einzelnen store

  • Der Status ist schreibgeschützt. Die einzige Möglichkeit, den Status zu ändern, besteht darin, ein spezielles Aktionsobjekt aufzurufen, das beschreibt, was mit dem Status geschehen soll
  • Änderungen werden mit reinen Funktionen vorgenommen - um festzustellen, welche Zustandsänderungen reducer , schreiben Sie die reine " reducer -Funktion, die keine Nebenwirkungen verursachen sollte "Link zum Beispielcode"


Link zum Originalbeitrag, aus dem das Bild stammt

Dieser Ansatz zur Verwaltung des Status wird von Webentwicklern weitgehend akzeptiert, und sein Auftreten auf Mobilgeräten wird den Entwicklern von Web- und Mobilanwendungen zugute kommen.

Brian Egan entwickelt sowohl das Original Redux als auch flutter_redux und er hat auch eine großartige Todo-Anwendung erstellt, in der er viele Architekturmuster angewendet hat, einschließlich Redux.
Angesichts aller Eigenschaften von Redux empfehle ich dringend, es zum Verwalten des globalen Status zu verwenden. Sie sollten jedoch sicher sein, dass Sie es nicht zum Verwalten des lokalen Status verwenden, wenn Sie Ihre Anwendung skalieren möchten.

Letzte Worte


In diesem Artikel gibt es keine vollständig korrekte oder falsche Lösung. Um zu entscheiden, welcher Ansatz in Ihrem Projekt angewendet werden soll, müssen Sie sich für Ihre Anforderungen entscheiden. Für mich und meine Ziele ermöglicht die Kombination von Redux und BLoC, dass meine Projekte schnell und sicher wachsen, und erleichtert Drittentwicklern dank zugänglicher und übersichtlicher Tools die Eingabe dieser Projekte. Allerdings hat nicht jeder die gleichen Bedürfnisse und im Laufe der Zeit können Sie sowohl Probleme "in aktuellen Tools" als auch noch bessere Lösungen finden. Es ist sehr wichtig, immer neugierig zu bleiben, zu studieren und zu überlegen, ob dieses oder jenes Tool zu Ihnen passt.

Source: https://habr.com/ru/post/de435780/


All Articles