Ist das Erweitern eines Widgets wirklich ein Antimuster?

Aug 20 2020

Ich habe an einigen Stellen gelesen, dass das Erweitern eines Flutter-Widgets ein Anti-Pattern ist. Ist das wahr?

Ich habe Widget-Unterklassen verwendet, um das Verschachteln zu reduzieren, indem ich das Widget, das ich entferne, in Unterklassen unterteilt und seine Widgets wie folgt in seinen Konstruktor eingefügt habe

class Foo extends FormBuilder {
    Foo() : super (
        // bunch of widgets here
    );
}

Das Erweitern eines zustandslosen Widgets scheint beliebter zu sein, fügt dem Baum jedoch ein paar weitere Codezeilen und ein Widget hinzu, was nicht meine Präferenz ist:

class Foo extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return FormBuilder(
       // bunch of widgets here
    );
}

Ich habe gelesen, dass das Zurückgeben eines Widgets von einer Funktion ein Antimuster ist, da es die Renderoptimierung unterbricht . Hat mein erster Ansatz ebenfalls versteckte Nebenwirkungen? Dh ist es wirklich ein Antimuster?

Antworten

3 kuhnroyal Aug 20 2020 at 20:22

Das Erweitern von Stateful-Widgets kann zu Problemen führen, da ihr Status in die Oberklasse eingegeben wird und Sie ihren Status nicht erweitern können, da die meisten Statusklassen privat bleiben. Viele der Suchmethoden wie BuildContext.findAncestorStateOfType()schlagen möglicherweise fehl.

Das Erweitern zustandsloser Widgets sollte in den meisten Fällen funktionieren, wird jedoch nicht empfohlen, wie Sie bereits festgestellt haben.

Im Allgemeinen ist bei der gesamten reaktiven und Widget-Natur von Flutter das Prinzip der Komposition über die Vererbung ein gutes Muster.

Sie komponieren Widgets zu neuen Widgets zu neuen Widgets zu neuen Widgets zu neuen Widgets ... Sie verstehen, worum es geht.

Außerdem speichern Sie 2 Codezeilen, die meistens automatisch generiert werden, aber Sie rauben sich alle einfachen Helfer in VSCode / IntelliJ wie "Widget mit Auffüllung umschließen". Es ist viel schwieriger, das Erweiterte FormBuildermit einer Polsterung für alle Verwendungen in Ihrer App zu versehen. Wenn Sie es komponieren, ist es einfach, wickeln Sie es einfach ein Foo. Gleiches gilt für alle anderen Widgets, die Sie für Themen, Farben, Schriftstile usw. verwenden. Das Auffüllen ist nur ein Beispiel.

2 jitsm555 Aug 20 2020 at 21:16

Flattern ist eher von compositionals Inheritance. Die Vererbung mit StatelessWidget ist jedoch immer dann nützlich, wenn übergeordnete Widgets im untergeordneten Widget wiederverwendet werden müssen.

Z.B:

class FormBuilder extends StatelessWidget {
  Widget getWidget() {
    return Text('Child Text');
  }

  @override
  Widget build(BuildContext context) {
    return Text('FormBuilder Text');
  }
}

class Foo extends FormBuilder {
  Foo() : super();

  @override
  Widget build(BuildContext context) {
    return getWidget();
  }
}

Also, Widget, das Foo () Widget aufruft, das der Widget-Elementbaum sein wird

- Foo

- Container

Wenn seine normale Zusammensetzung dann Element Baum würde dafür sein

class Foo extends StatelessWidget {
      Foo() : super();
    
      @override
      Widget build(BuildContext context) {
        return FormBuilder();
      }
    }

- Foo

- FormBuilder

- Text

Es gibt kein offizielles Dokument, das sein schlechtes Muster sagt, sondern ein Flattern, das unter Berücksichtigung entworfen wurde Composition. Ich persönlich habe also nie ein solches Leistungs- oder Verzögerungsproblem bei der Vererbung beobachtet, daher würde ich vorschlagen, dass Inheritancees keine schlechte Wahl ist, es zu verwenden.