|
| 1 | +# Mejores Prácticas |
| 2 | + |
| 3 | +Patrones listos para producción, anti-patrones, y guías para usar `command_it` efectivamente. |
| 4 | + |
| 5 | +## Cuándo Usar Commands |
| 6 | + |
| 7 | +### ✅ Usa Commands Para |
| 8 | + |
| 9 | +**Operaciones async con feedback de UI:** |
| 10 | + |
| 11 | +<<< @/../code_samples/lib/command_it/best_practices_when_to_use.dart#async_ui_feedback |
| 12 | + |
| 13 | +**Operaciones que pueden fallar:** |
| 14 | + |
| 15 | +<<< @/../code_samples/lib/command_it/best_practices_when_to_use.dart#operations_can_fail |
| 16 | + |
| 17 | +**Acciones disparadas por usuario:** |
| 18 | + |
| 19 | +<<< @/../code_samples/lib/command_it/best_practices_when_to_use.dart#user_triggered |
| 20 | + |
| 21 | +**Operaciones que necesitan tracking de estado:** |
| 22 | +- Estados de carga de botones |
| 23 | +- Pull-to-refresh |
| 24 | +- Envío de formularios |
| 25 | +- Peticiones de red |
| 26 | +- I/O de archivos |
| 27 | + |
| 28 | +### ✅ Usa Commands Sync para Input con Operadores |
| 29 | + |
| 30 | +Cuando necesitas aplicar operadores (debounce, map, where) a input de usuario antes de disparar otras operaciones: |
| 31 | + |
| 32 | +<<< @/../code_samples/lib/command_it/best_practices_when_to_use.dart#sync_input_operators |
| 33 | + |
| 34 | +Esto es diferente de simples getters/setters porque: |
| 35 | +- Captura input de usuario como un stream de valores |
| 36 | +- Usa operadores como `.debounce()` para procesar el stream |
| 37 | +- Encadena para disparar otros commands |
| 38 | + |
| 39 | +**Ver también:** El [ejemplo de clima](https://github.com/flutter-it/command_it/blob/main/example/lib/weather_manager.dart) demuestra este patrón con `textChangedCommand`. |
| 40 | + |
| 41 | +### ❌️️ No Uses Commands Para |
| 42 | + |
| 43 | +**Simples getters/setters (sin operadores o encadenamiento):** |
| 44 | + |
| 45 | +<<< @/../code_samples/lib/command_it/best_practices_when_to_use.dart#dont_use_getter |
| 46 | + |
| 47 | +**Cómputos puros sin efectos secundarios:** |
| 48 | + |
| 49 | +<<< @/../code_samples/lib/command_it/best_practices_when_to_use.dart#dont_use_computation |
| 50 | + |
| 51 | +**Cambios de estado inmediatos:** |
| 52 | + |
| 53 | +<<< @/../code_samples/lib/command_it/best_practices_when_to_use.dart#dont_use_toggle |
| 54 | + |
| 55 | +## Patrones de Organización |
| 56 | + |
| 57 | +### Patrón 1: Commands en Managers |
| 58 | + |
| 59 | +<<< @/../code_samples/lib/command_it/best_practices_organization.dart#managers_managers |
| 60 | + |
| 61 | +**Beneficios:** |
| 62 | +- Lógica de negocio centralizada |
| 63 | +- Fácil testing |
| 64 | +- Reutilizable entre widgets |
| 65 | +- Propiedad clara |
| 66 | + |
| 67 | +### Patrón 2: Organización Basada en Features |
| 68 | + |
| 69 | +<<< @/../code_samples/lib/command_it/best_practices_organization.dart#feature_based |
| 70 | + |
| 71 | +### Patrón 3: Commands en Data Proxies |
| 72 | + |
| 73 | +Los Commands también pueden vivir en objetos de datos que gestionan sus propias operaciones async. Esto es útil cuando cada item de datos necesita estado de carga independiente: |
| 74 | + |
| 75 | +<<< @/../code_samples/lib/command_it/best_practices_organization.dart#proxy_pattern |
| 76 | + |
| 77 | +**Beneficios:** |
| 78 | +- Cada item tiene estado de carga/error independiente |
| 79 | +- La lógica de caching vive con los datos |
| 80 | +- La UI puede observar estado de item individual |
| 81 | +- El manager se mantiene simple (solo crea/cachea proxies) |
| 82 | + |
| 83 | +## Cuándo Usar runAsync() |
| 84 | + |
| 85 | +Como se explica en [Fundamentos de Command](/es/documentation/command_it/command_basics), el patrón central de command es **dispara-y-olvida**: llama `run()` y deja que tu UI observe cambios de estado reactivamente. Sin embargo, hay casos legítimos donde usar `runAsync()` es apropiado y más expresivo que las alternativas. |
| 86 | + |
| 87 | +### ✅ Usa runAsync() Para Flujos de Trabajo Secuenciales |
| 88 | + |
| 89 | +Cuando los commands son parte de un flujo de trabajo async más grande mezclado con otras operaciones async: |
| 90 | + |
| 91 | +<<< @/../code_samples/lib/command_it/best_practices_run_async.dart#async_workflow |
| 92 | + |
| 93 | +**¿Por qué `runAsync()` aquí?** El command es parte de una función async más grande que mezcla ejecución de commands con llamadas async regulares. Usar `runAsync()` mantiene el código lineal y legible. |
| 94 | + |
| 95 | +### ✅ Usa runAsync() Para APIs que Requieren Futures |
| 96 | + |
| 97 | +Cuando interactúas con APIs que requieren un `Future`: |
| 98 | + |
| 99 | +<<< @/../code_samples/lib/command_it/best_practices_run_async.dart#api_futures |
| 100 | + |
| 101 | +### ❌️ No Uses runAsync() para Actualizaciones de UI Simples |
| 102 | + |
| 103 | +<<< @/../code_samples/lib/command_it/best_practices_run_async.dart#dont_use_runasync |
| 104 | + |
| 105 | +### Resumen |
| 106 | + |
| 107 | +**Usa `runAsync()` cuando:** |
| 108 | +- ✅ Los commands son parte de un flujo de trabajo async más grande |
| 109 | +- ✅ Una API requiere que se retorne un Future |
| 110 | +- ✅ El flujo secuencial es más claro con `await` que con `.listen()` |
| 111 | + |
| 112 | +**No uses `runAsync()` cuando:** |
| 113 | +- ❌️ Disparando commands desde interacciones de UI (usa `run()`) |
| 114 | +- ❌️ Solo quieres observar resultados (usa `watchValue()` o `ValueListenableBuilder`) |
| 115 | +- ❌️ El async/await no agrega valor sobre dispara-y-olvida |
| 116 | + |
| 117 | +## Mejores Prácticas de Rendimiento |
| 118 | + |
| 119 | +### Debounce de Input de Texto |
| 120 | + |
| 121 | +<<< @/../code_samples/lib/command_it/best_practices_performance.dart#debounce |
| 122 | + |
| 123 | +### Dispose de Commands Apropiadamente |
| 124 | + |
| 125 | +<<< @/../code_samples/lib/command_it/best_practices_performance.dart#dispose |
| 126 | + |
| 127 | +### Evitar Rebuilds Innecesarios |
| 128 | + |
| 129 | +<<< @/../code_samples/lib/command_it/best_practices_performance.dart#rebuilds |
| 130 | + |
| 131 | +## Mejores Prácticas de Restricciones |
| 132 | + |
| 133 | +### Usa isRunningSync para Dependencias de Commands |
| 134 | + |
| 135 | +<<< @/../code_samples/lib/command_it/best_practices_restriction.dart#isrunningsync |
| 136 | + |
| 137 | +### La Lógica de Restricción Está Invertida |
| 138 | + |
| 139 | +<<< @/../code_samples/lib/command_it/best_practices_restriction.dart#inverted |
| 140 | + |
| 141 | +## Anti-Patrones Comunes |
| 142 | + |
| 143 | +### ❌️️ No Escuchar Errores |
| 144 | + |
| 145 | +<<< @/../code_samples/lib/command_it/best_practices_antipatterns.dart#not_listening_errors |
| 146 | + |
| 147 | +### ❌️️ Try/Catch Dentro de Commands |
| 148 | + |
| 149 | +No uses try/catch dentro de funciones de commands - derrota el sistema de manejo de errores de `command_it`: |
| 150 | + |
| 151 | +<<< @/../code_samples/lib/command_it/best_practices_antipatterns.dart#try_catch_inside |
| 152 | + |
| 153 | +## Ver También |
| 154 | + |
| 155 | +- [Fundamentos de Command](/es/documentation/command_it/command_basics) — Primeros pasos |
| 156 | +- [Manejo de Errores (Error Handling)](/es/documentation/command_it/error_handling) — Gestión de errores |
| 157 | +- [Testing](/es/documentation/command_it/testing) — Patrones de testing |
| 158 | +- [Observando Commands con `watch_it`](/es/documentation/watch_it/observing_commands) — Patrones de UI reactiva |
0 commit comments