Лучшие практики Flutter

В этом разделе будут представлены лучшие практики и стандарты кодирования при разработке на Flutter.


Стандарты кода

Соглашения об именовании

TypeПравилаПример
Имя классаUpperCamelCaseMyHomePage
Функции/ПеременныеlowerCamelCaseuserName, getData
КонстантыВерхний Camel Case + префикс kkMaxCount
ФайлНижний регистр + подчеркиваниеmy_home_page.dart

Пример: правильное именование

// Имя класса - UpperCamelCase
class UserProfilePage extends StatelessWidget {}

// Функция - lowerCamelCase
void fetchUserData() {}

// Переменная - lowerCamelCase
String userName = 'Zhang San';

// Константы - префикс k
const int kMaxRetryCount = 3;
const String kAppName = 'My App';

// Перечисление - UpperCamelCase
enum AppState { loading, success, error }

// Имя файла - snake_case
// user_profile_page.dart

Оптимизация производительности

1. Избегайте ненужных перестроек

Пример: Использование const-конструктора

// Рекомендуется: используйте const для уменьшения перестроек
const Text('Hello')              // Не будет перестраиваться
const SizedBox(width: 10)

// Избегайте: каждая сборка создаёт новый объект
Text('Hello')                   // Будет перестраиваться

// Используйте const в списках
ListView(
  children: const [
    Текст('A'),
    Текст('B'),
    Текст('C'),
  ],
)

2. Используйте ключи для оптимизации производительности списка

Пример: правильное использование ключей

// Добавьте уникальные ключи к элементам списка
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      key: ValueKey(items[index].id),  // Используйте уникальные идентификаторы в качестве ключей
      title: Text(items[index].name),
    );
  },
)

3. Ленивая загрузка элементов списка

Пример: использование ListView.builder

// Рекомендуется: используйте builder для ленивой загрузки
ListView.builder(
  itemCount: 1000,  // Обязательно использовать для больших списков
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item $index'));
  },
)

// Избегайте использования children для построения больших списков
ListView(
  children: List.generate(1000, (i) => Text('Item $i')),
)

Структура проекта

Пример: рекомендуемая структура проекта

// lib/
// ├── main.dart # входной файл
// ├── app.dart # конфигурация приложения
// ├── core/ # основная функциональность
// │ ├── constants/ # константы
// │ ├── theme/ # тема
// │ ├── utils/ # вспомогательные классы
// │ └── extensions/ # расширения
// ├── data/ # слой данных
// │ ├── models/ # модели данных
// │ ├── repositories/ # Репозитории
// │ └── services/ # Сетевые сервисы
// ├── domain/ # Доменный слой
// │ └── entities/ # Сущности
// ├── presentation/ # Слой представления
// │ ├── pages/ # Страницы
// │ ├── widgets/ # Виджеты
// │ └── providers/ # Управление состоянием
// └── routes/ # Маршруты

Обработка ошибок

Пример: Глобальная обработка ошибок

void main() {
  // Глобальный перехват исключений
  FlutterError.onError = (details) {
    // Логирование ошибки
    print('Flutter Error: ${details.exception}');
    // Отправить ошибку на сервер
    reportError(details.exception);
  };

  // Перехват исключений Zone
  runZonedGuarded(() {
    runApp(const MyApp());
  }, (error, stackTrace) {
    print('Ошибка зоны: $error');
    reportError(error);
  });
}

Следование лучшим практикам делает код более поддерживаемым, повышает производительность и уменьшает количество ошибок в продакшене.

Другие расширения