← Dart EspañolChapter 13 of 13

Mejores Practicas

## Objetivos de Aprendizaje - Seguir la guia de estilo de Dart - Escribir codigo limpio y mantenible - Dominar patrones efectivos - Aprender practicas especificas de Flutter ## Convenciones de Nombres ### Variables y Funciones ```dart // Variables: camelCase var userName = 'Alice'; var isActive = true; var itemCount = 42; // Funciones: camelCase void fetchUserData() {} int calculateTotal() {} // Miembros privados: guion bajo al inicio class User { String _privateField = ''; void _privateMethod() {} } ``` ### Clases y Tipos ```dart // Clases: PascalCase class UserAccount {} class HttpClient {} class ApiResponse {} // Enums: PascalCase enum Status { pending, active, completed } enum Color { red, green, blue } // Alias de tipos: PascalCase typedef UserId = String; typedef Callback = void Function(); ``` ### Constantes ```dart // Constantes de tiempo de compilacion: PascalCase const int maxItems = 100; const String appName = 'MyApp'; // Valores de enum: camelCase (pero mantener enum PascalCase) enum Status { isPending, isActive, isCompleted, } ``` ### Archivos ```dart // lowercase_with_underscores.dart // user_repository.dart // api_client.dart // constants.dart ``` ## Organizacion del Codigo ### Estructura de Archivos ```dart // person.dart class Person { String name; int age; Person(this.name, this.age); void greet() => print('Hola, soy $name'); } ``` ### Organizacion de Importaciones ```dart // Orden: SDK, paquete, relativo import 'dart:async'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import '../models/user.dart'; import 'constants.dart'; ``` ## Variables ### Preferir var para Variables Locales ```dart // Bien: el tipo es claro desde el lado derecho var name = 'Alice'; var count = 0; var items = ['a', 'b', 'c']; // Aceptable: explicito cuando el tipo no es obvio var points = []; var mapping = {}; ``` ### Final Cuando Sea Posible ```dart // Usar final para valores que no cambian final name = 'Alice'; final items = ['a', 'b', 'c']; // Usar const para constantes de tiempo de compilacion const maxRetries = 3; const defaultTimeout = Duration(seconds: 30); ``` ### Evitar var para Campos Publicos ```dart // Bien: tipo explicito para API publica class User { final String name; final int age; User(this.name, this.age); } // Aceptable: var para variables locales con contexto claro var result = computeResult(); ``` ## Funciones ### Preferir Funciones Flecha para Funciones Cortas ```dart // Bien int square(int x) => x * x; String capitalize(String s) => s.isEmpty ? '' : s[0].toUpperCase() + s.substring(1); // Evitar para logica compleja void process() { // Logica compleja aqui // Multiples sentencias // No usar flecha para multi-linea } ``` ### Usar Void Solo para Efectos Secundarios ```dart // Bien: devuelve valor Future fetchUser(String id) async { ... } // Bien: void para efectos secundarios solamente Future saveUser(User user) async { ... } // Evitar: devolviendo valor pero declarado void // void process() => computeResult(); // Confuso ``` ## Clases ### Preferir Constructores con Lista de Inicializacion ```dart class Point { final double x; final double y; Point(this.x, this.y); // Bien // Evitar: parametros nombrados innecesarios para casos simples // Point({required this.x, required this.y}); // Exceso aqui } ``` ### Usar Constructores Nombrados para Claridad ```dart class Date { int year; int month; int day; Date(this.year, this.month, this.day); // Constructores nombrados para claridad Date.today() : this(DateTime.now().year, DateTime.now().month, DateTime.now().day); Date.fromJson(Map json) : this(json['year'], json['month'], json['day']); } ``` ### Campos Privados para Encapsulacion ```dart class BankAccount { String _accountNumber; // Privado double _balance; // Privado BankAccount(this._accountNumber, this._balance); double get balance => _balance; // Acceso solo lectura void deposit(double amount) { if (amount > 0) _balance += amount; } } ``` ## Seguridad Null ### Evitar Desenvoltura Forzada (!) ```dart // Mal String name = getName()!; // Bien: manejar null explicitamente String? name = getName(); String displayName = name ?? 'Desconocido'; ``` ### Preferir Late con Moderacion ```dart // Bien: cuando se necesita inicializacion perezosa class DataService { late String data; // Diferir inicializacion Future load() async { data = await fetchData(); } } // Mejor: si es posible, inicializar en el constructor class User { final String name; User(this.name); } ``` ## Colecciones ### Preferir Literales de Coleccion ```dart // Bien var list = [1, 2, 3]; var map = {'a': 1, 'b': 2}; var set = {1, 2, 3}; // Evitar: constructor List<>() // var list = List.of([1, 2, 3]); // Verbose ``` ### Usar Operadores de Propagacion ```dart var base = [1, 2, 3]; var combined = [0, ...base, 4]; // [0, 1, 2, 3, 4] var defaults = {'a': 1, 'b': 2}; var overrides = {'b': 3, 'c': 4}; var config = {...defaults, ...overrides}; ``` ### Condicionales en Colecciones ```dart var isPremium = true; var items = [ 'Inicio', if (isPremium) 'Caracteristica Premium', 'Acerca de', ]; var filtered = [1, 2, 3, 4, 5] .where((n) => n % 2 == 0) .map((n) => n * 2) .toList(); ``` ## Programacion Asincrona ### async/await Sobre Futures ```dart // Bien: flujo asincrono claro Future loadData() async { try { var user = await fetchUser(); var posts = await fetchPosts(user.id); print('Publicaciones: $posts'); } catch (e) { print('Error: $e'); } } // Evitar: encadenamiento excesivo de then // fetchUser().then((user) => fetchPosts(user.id)).then(...); ``` ### Cancelar Futures No Usados ```dart class MyWidget extends StatefulWidget { @override State createState() => _MyWidgetState(); } class _MyWidgetState extends State { Future? _future; @override void initState() { super.initState(); _future = loadData(); } @override void dispose() { _future = null; // Ayudar a garbage collection super.dispose(); } } ``` ## Manejo de Errores ### Excepciones Especificas ```dart try { await fetchData(); } on NetworkException { // Manejar errores de red showNetworkError(); } on ServerException catch (e) { // Manejar errores de servidor con contexto showServerError(e.message); } catch (e, stack) { // Errores inesperados reportError(e, stack); } ``` ### Patron Result ```dart class Result { final T? data; final String? error; Result.success(this.data) : error = null; Result.failure(this.error) : data = null; bool get isSuccess => data != null; } Future> fetchUser() async { try { var user = await _api.getUser(); return Result.success(user); } catch (e) { return Result.failure(e.toString()); } } ``` ## Especifico de Flutter ### StatelessWidget vs StatefulWidget ```dart // Usar StatelessWidget cuando sea posible class Counter extends StatelessWidget { final int count; const Counter({required this.count}); @override Widget build(BuildContext context) { return Text('Conteo: $count'); } } ``` ### Widgets Const ```dart // Bien: const cuando sea posible return const Text('Hola'); // Bien: constructor const class MyWidget extends StatelessWidget { const MyWidget({super.key}); @override Widget build(BuildContext context) { return const Text('Hola'); } } ``` ### Evitar setState Cuando Sea Posible ```dart // Bien: derivar de estado existente Text('Conteo: $props.count'); // Considerar: Riverpod, Provider, Bloc para estado complejo ``` ## Documentacion ### Usar Comentarios de Documentacion ```dart /// Calcula la suma de dos numeros. /// /// [a] El primer numero /// [b] El segundo numero /// /// Devuelve la suma de a y b int sum(int a, int b) => a + b; ``` ## Resumen - Seguir nombres: camelCase (vars), PascalCase (tipos) - Usar final para inmutable, const para tiempo de compilacion - Preferir var para variables locales con tipos claros - Usar constructores const en Flutter - Manejar null安全的: preferir `??` sobre `!` - Usar async/await sobre Future.then - Ser especifico con excepciones - Documentar APIs publicas con comentarios de documentacion - Mantener archivos cortos y enfocados

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →