Flutter Best Practices

In diesem Abschnitt werden Best Practices und Codierungsstandards in der Flutter-Entwicklung vorgestellt.


Code-Standards

Namenskonventionen

TypeRegelnBeispiel
KlassennameUpperCamelCaseMyHomePage
Funktionen/VariablenlowerCamelCaseuserName, getData
KonstantenUpper Camel Case + k-PräfixkMaxCount
DateiKleinschreibung + Unterstrichmy_home_page.dart

Beispiel: Korrekte Benennung

// Klassenname - UpperCamelCase
class UserProfilePage extends StatelessWidget {}

// Funktion - lowerCamelCase
void fetchUserData() {}

// Variable - lowerCamelCase
String userName = 'Zhang San';

// Konstanten - k-Präfix
const int kMaxRetryCount = 3;
const String kAppName = 'My App';

// Enum - UpperCamelCase
enum AppState { loading, success, error }

// Dateiname - snake_case
// user_profile_page.dart

Leistungsoptimierung

1. Unnötige Rebuilds vermeiden

Beispiel: Verwendung des const-Konstruktors

// Empfohlen: const verwenden, um Rebuilds zu reduzieren
const Text('Hello')              // Wird nicht neu aufgebaut
const SizedBox(width: 10)

// Vermeiden: Jeder Build erstellt ein neues Objekt
Text('Hello')                   // Wird neu aufgebaut

// const in Listen verwenden
ListView(
  children: const [
    Text('A'),
    Text('B'),
    Text('C'),
  ],
)

2. Verwende Keys zur Optimierung der Listen-Performance

Beispiel: Keys korrekt verwenden

// Eindeutige Keys zu Listenelementen hinzufügen
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      key: ValueKey(items[index].id),  // Eindeutige Identifikatoren als Keys verwenden
      title: Text(items[index].name),
    );
  },
)

3. Lazy Loading von Listenelementen

Beispiel: Verwendung von ListView.builder

// Empfohlen: builder für Lazy Loading verwenden
ListView.builder(
  itemCount: 1000,  // Muss für große Listen verwendet werden
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item $index'));
  },
)

// Vermeiden: children zum Erstellen großer Listen verwenden
ListView(
  children: List.generate(1000, (i) => Text('Item $i')),
)

Projektstruktur

Beispiel: Empfohlene Projektstruktur

// lib/
// ├── main.dart # Einstiegsdatei
// ├── app.dart # App-Konfiguration
// ├── core/ # Kernfunktionalität
// │ ├── constants/ # Konstanten
// │ ├── theme/ # Design
// │ ├── utils/ # Hilfsklassen
// │ └── extensions/ # Erweiterungen
// ├── data/ # Datenschicht
// │ ├── models/ # Datenmodelle
// │ ├── repositories/ # Repositories
// │ └── services/ # Netzwerkdienste
// ├── domain/ # Domänenschicht
// │ └── entities/ # Entitäten
// ├── presentation/ # Präsentationsschicht
// │ ├── pages/ # Seiten
// │ ├── widgets/ # Widgets
// │ └── providers/ # Zustandsverwaltung
// └── routes/ # Routen

Fehlerbehandlung

Beispiel: Globale Fehlerbehandlung

void main() {
  // Globale Ausnahmenerfassung
  FlutterError.onError = (details) {
    // Fehler protokollieren
    print('Flutter Error: ${details.exception}');
    // Fehler an Server melden
    reportError(details.exception);
  };

  // Zonen-Ausnahmenerfassung
  runZonedGuarded(() {
    runApp(const MyApp());
  }, (error, stackTrace) {
    print('Zone Error: $error');
    reportError(error);
  });
}

Die Befolgung bewährter Methoden kann Code wartbarer machen, die Leistung verbessern und Fehler in der Produktion reduzieren.

Weitere Erweiterungen