Módulo 02: POO Avanzada en Dart

Extension Methods

Extension Methods

# Extension Methods en Dart Los Extension Methods, introducidos en Dart 2.7, te permiten agregar funcionalidad a librerías existentes sin modificar su código fuente y sin crear subclases. ## Sintaxis Básica ```dart extension on { // Métodos, getters, setters } ``` ### Ejemplo: String Extensions ```dart extension StringUtils on String { // Método nuevo bool get isValidEmail { return contains('@') && contains('.'); } // Capitalizar primera letra String capitalize() { if (isEmpty) return this; return '${this[0].toUpperCase()}${substring(1)}'; } // Operador String operator &(String other) => '$this $other'; } void main() { String email = '[email protected]'; // Uso natural, como si fuera parte de la clase String if (email.isValidEmail) { print(email.capitalize()); } print('Hello' & 'World'); // "Hello World" } ``` ## Extensiones en Flutter Son extremadamente útiles para simplificar código de UI repetitivo. ### 1. Context Extensions Evita escribir `MediaQuery.of(context)` o `Theme.of(context)` repetidamente. ```dart extension ContextExtensions on BuildContext { // Dimensiones double get width => MediaQuery.of(this).size.width; double get height => MediaQuery.of(this).size.height; // Tema ThemeData get theme => Theme.of(this); TextTheme get textTheme => Theme.of(this).textTheme; ColorScheme get colors => Theme.of(this).colorScheme; // Navegación void push(Widget page) { Navigator.of(this).push(MaterialPageRoute(builder: (_) => page)); } void pop() => Navigator.of(this).pop(); } // Uso en Widget class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Container( width: context.width * 0.8, // ✅ Más limpio color: context.colors.primary, child: Text( 'Hello', style: context.textTheme.headline6, ), ); } } ``` ### 2. Widget Extensions (Padding, Center, etc.) Estilo "Modifier" similar a SwiftUI. ```dart extension WidgetExtensions on Widget { Widget paddingAll(double value) => Padding( padding: EdgeInsets.all(value), child: this, ); Widget center() => Center(child: this); Widget expanded({int flex = 1}) => Expanded( flex: flex, child: this, ); } // Uso encadenado Widget build(BuildContext context) { return Text('Hello') .paddingAll(16.0) .center() .expanded(); } ``` ### 3. Iterable Extensions Operaciones útiles en listas. ```dart extension IterableExtensions on Iterable { // Obtener elemento o null si fuera de rango T? getOrNull(int index) { if (index < 0 || index >= length) return null; return elementAt(index); } // Separar elementos con un separador Iterable separate(T separator) sync* { final iterator = this.iterator; if (!iterator.moveNext()) return; yield iterator.current; while (iterator.moveNext()) { yield separator; yield iterator.current; } } } // Uso final list = [1, 2, 3]; print(list.getOrNull(10)); // null // Útil en Rows/Columns para agregar espacios final widgets = [Text('A'), Text('B')]; final spaced = widgets.separate(SizedBox(width: 10)); ``` ## Extensiones Genéricas Puedes extender tipos genéricos. ```dart extension ListExtensions on List { // Swap seguro void safeSwap(int index1, int index2) { if (index1 >= 0 && index1 < length && index2 >= 0 && index2 < length) { final temp = this[index1]; this[index1] = this[index2]; this[index2] = temp; } } } ``` ## Resolución de Conflictos Si dos extensiones definen el mismo método, Dart te pedirá que seas explícito o importes solo una. ```dart // Si hay conflicto: ExtensionName(objeto).metodo(); ``` ## Conclusión Los Extension Methods son una herramienta fantástica para: - **Legibilidad**: Código más limpio y expresivo. - **Utilidad**: Agregar helpers a clases que no controlas (SDK, librerías). - **Productividad**: Reducir boilerplate en Flutter. ¡Úsalos con responsabilidad! No conviertas todo en una extensión.

Este apartado profundiza en los conceptos clave, proporcionando ejemplos prácticos y mejores prácticas para su aplicación en proyectos reales.

Al comprender estos detalles, podrás diseñar soluciones más robustas, mantenibles y escalables en tus aplicaciones Flutter y Dart.