Métodos para refactorizar un widget

Para que el código sea más legible y fácil de mantener, en ocasiones se pueden refactorizar algunas secciones del código en entidades separadas. Para ello podemos utilizar distintas técnicas, como crear constantes, métodos y clases de widgets (desde Android Studio o VS Code tenemos rápido acceso a estas acciones desde Refactorizar y después elegir, respectivamente, Extract Local (Variable / Constant), Extract Method o Extract Widget).

Para refactorizar con una constante, simplemente inicializamos una variable como final y después la insertamos donde la necesitamos:

final contenedor = Container(
    color: Colors.deepOrange,
    height: 40.0,
    width: 40.0,
);

También se puede usar una función o método utilizando el objeto BuildContext del widget principal para devolver un widget general (Widget) o un widget específico:

Widget _buildContainer() {  // Container _buildContainer() {
    return Container(
        color: Colors.deepOrange,
        height: 40.0,
        width: 40.0,
    );
}

Estas dos maneras permiten separar widgets en secciones, lo que mejora la legibilidad del código. Sin embargo cada vez que se redibuja el widget principal, también se redibujarán los widgets refactorizados con constantes y métodos, lo que afecta al rendimiento.

Refactorizar con una clase puede ser la mejor manera de crear widgets reutilizables porque al llamarlos con la palabra const (para eso el constructor de esa clase también debe utilizar const), el widget no se reconstruye cuando otros widgets cambian su estado. Esto significa que cada vez que se vuelve a dibujar el widget principal o actualizarse la pantalla, no se volverán a reconstruir todos los widgets. Además, a diferencia de la refactorización con un método, la clase de widget se basa en su propio BuildContext, no en el del widget padre.

class Contenedor extends StatelessWidget {
  const Contenedor({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.deepOrange,
      height: 40.0,
      width: 40.0,
    );
  }
}

Y para inicializar el widget lo invocamos con:

const Contenedor(),