Principios Comunes de Arquitectura

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:

  1. El usuario presiona un botón en la UI Layer.
  2. La lógica (Logic Layer) decide qué hacer.
  3. La capa de datos (Data Layer) guarda el cambio.
  4. 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.

Comentarios

Youtube