¿Es realmente un antipatrón extender un widget?

Aug 20 2020

He leído en un par de lugares que extender un widget Flutter es un anti-patrón. ¿Es eso cierto?

He usado subclases de widgets para reducir el anidamiento subclasificando el widget que estoy eliminando y colocando sus widgets en su constructor, así

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

Extender un widget sin estado parece más popular, pero agrega algunas líneas más de código y un widget al árbol, que no es mi preferencia:

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

He leído que devolver un widget desde una función es un antipatrón porque rompe la optimización de la representación . ¿Mi primer enfoque también tiene efectos secundarios ocultos? Es decir, ¿es realmente un antipatrón?

Respuestas

3 kuhnroyal Aug 20 2020 at 20:22

La extensión de los widgets con estado puede generar problemas, ya que su estado se escribe en la superclase y no se puede extender su estado, ya que la mayoría de las clases estatales se mantienen privadas. Muchos de los métodos de búsqueda como BuildContext.findAncestorStateOfType()potencialmente fallarán.

La extensión de los widgets sin estado debería funcionar en la mayoría de los casos, pero no se recomienda, como ya ha descubierto.

En general, con toda la naturaleza reactiva y de widget de Flutter, el principio de composición sobre la herencia es un buen patrón a seguir.

Usted compone widgets en nuevos widgets en nuevos widgets en nuevos widgets en nuevos widgets ...

Además de eso, guarda 2 líneas de código que en su mayoría se generan automáticamente, pero se priva de todos los ayudantes simples en VSCode / IntelliJ como "Wrap Wrap with padding". Es mucho más difícil envolver el extendido FormBuildercon un relleno en todos los usos de su aplicación. Si lo compones es simple, simplemente envuélvelo dentro Foo. Lo mismo ocurre con todos los demás widgets que usa para temas, colores, estilos de fuente, etc. - el relleno es solo un ejemplo.

2 jitsm555 Aug 20 2020 at 21:16

Flutter es más de en compositionlugar de Inheritance. Pero la herencia con StatelessWidget siempre será útil cuando los widgets principales deben reutilizarse en el niño.

P.ej:

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();
  }
}

Entonces, Widget que llamará Foo () Widget que el árbol de Widget Element será

- Foo

-- Envase

Si su composición normal, el árbol de elementos sería para esto

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

- Foo

- FormBuilder

- texto

No hay ningún documento oficial que diga su mal patrón pero aleteo diseñado teniendo Compositionen cuenta. Por lo tanto, personalmente nunca observé ningún problema de rendimiento o retraso con la herencia, por lo que sugeriría Inheritanceque no es una mala elección usarlo.