Conceptos de Arquitectura en Flutter
1. Principios Comunes de Arquitectura
Separación de responsabilidades (Separation of Concerns):
- Dividir la aplicación en partes independientes y especializadas.
- Ejemplo real: En una cocina, los cocineros preparan platos mientras los meseros los llevan a los clientes.
- En Flutter: Separa la lógica del negocio de la lógica de UI.
2. Arquitectura en Capas (Layered Architecture)
Dividir la aplicación en capas con propósitos claros:
- UI Layer: Muestra datos al usuario y captura interacciones.
- Logic Layer: Procesa reglas de negocio y toma decisiones.
- Data Layer: Gestiona fuentes de datos como bases de datos o APIs remotas.
Ejemplo visual: El mesero (UI Layer) toma el pedido y lo entrega al chef (Logic Layer), quien usa ingredientes del almacén (Data Layer).
3. Fuente Única de Verdad (Single Source of Truth - SSOT)
Cada tipo de dato debe tener un único lugar donde se almacena y gestiona.
Ejemplo básico de repositorio:
class UserRepository {
final _users = ['Alice', 'Bob'];
List getUsers() => _users;
void addUser(String user) {
_users.add(user);
}
}
4. Flujo de Datos Unidireccional (Unidirectional Data Flow - UDF)
Los datos fluyen desde la fuente de datos (Data Layer) hasta la UI Layer, y las interacciones del usuario regresan por el camino contrario.
Ejemplo:
- El usuario presiona un botón en la UI Layer.
- La lógica (Logic Layer) decide qué hacer.
- La capa de datos (Data Layer) guarda el cambio.
- La nueva información regresa al Logic Layer y luego actualiza la UI Layer.
5. La UI es una Función del Estado
Flutter usa un enfoque declarativo: la interfaz gráfica depende del estado actual.
Ejemplo básico:
final counterProvider = StateProvider((ref) => 0);
class CounterApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
return Scaffold(
appBar: AppBar(title: Text('Contador')),
body: Center(child: Text('Valor: $counter')),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(counterProvider.notifier).state++;
},
child: Icon(Icons.add),
),
);
}
}
6. Extensibilidad
Tu arquitectura debe ser flexible para agregar nuevas funcionalidades sin romper las existentes.
7. Testeabilidad
Un buen diseño arquitectónico facilita las pruebas automáticas.
Resumen Práctico
- Divide tu app en capas: UI Layer, Logic Layer, Data Layer.
- Sigue el flujo de datos unidireccional.
- Usa una fuente única de verdad para tus datos: repositorios.
- Diseña tus componentes de forma extensible y testeable.