Цвет и стиль: глобальная константа против темы

Сегодня я искал статьи о Flutter и нашел статью Деррита Мвити с заголовком Лучшие практики разработки Flutter. Я учусь трепетать с января 2020 года и считаю, что очень важно не привыкать к вредным привычкам. Поэтому такие статьи мне очень интересны. Я могу понять большинство практик, рекомендованных Дерритом. Но первый в его списке заставил меня усомниться.

Неужели темы такие классные?

Он начинает с совета по использованию тем и указывает на следующие преимущества:

  • С ссылками на свойства в любом месте кода проще.
  • Это предотвращает повторение кода
  • Легче настроить свойство в одном месте и увидеть изменения повсюду.

Затем он дает несколько примеров кода, чтобы показать, как темы определены и как они используются.

Это все хорошо, но мне пришло в голову, что все эти преимущества также могут быть достигнуты с помощью простых глобальных констант. Впервые я увидел эти глобалы в исходном коде Dane Mackier на github. В своем проекте 014 он определяет цвета и шрифты с помощью глобальных констант в таких файлах, как app_colors.dart и textstyles.dart.

Я обнаружил похожую практику в великолепном курсе Анжелы Ю на Удеми. У нее есть файл под названием constants.dart, в котором все стили текста определены в одном месте.

Поэтому я задал себе вопрос: как можно взвесить плюсы и минусы этих двух практик? Что лучше"?

Давайте сначала посмотрим, достигаются ли три преимущества стандартной флаттер-темы с помощью global const.

С ссылками на свойства в любом месте кода проще.

Это еще проще с глобальными константами. Всплывающее окно Intellisense перечисляет все определенные константы, как только я ввожу маленький k. Это соглашение также используется в исходном коде Googles flutter и dart.

Это предотвращает повторение кода

Это тоже достигается. Определите константу один раз и используйте ее где угодно.

Легче настроить свойство в одном месте и увидеть изменения везде.

Это применимо и здесь. Если я настрою глобальную константу, все виджеты, которые ее используют, изменятся.

На стороне глобалов еще больше преимуществ?

Что ж, на мой взгляд, есть: меньше кода. И чем меньше, тем лучше, правда?

Обычно на свойство чаще ссылаются, чем на определение. Итак, давайте сначала посмотрим, как используются свойства.

Например цвет:

backgroundColor: Theme.of(context).accentColor,

or

backgroundColor: kAccentColor,

и стиль текста:

Text("Theming",style: Theme.of(context).textTheme.title,)

or

Text("Theming",style: kStyleTitle,)

В обоих случаях использование константного значения короче.

По моему мнению, определение свойств также проще. Я помню, что видел определения тем, но не могу вспомнить точный синтаксис и возможные сочетания клавиш с copyWith и так далее.

Что-то вроде этого примера от Деррита:

theme: ThemeData( 
  primarySwatch: Colors.lightBlue, 
  accentColor: Colors.teal, 
  fontFamily: 'Lato', 
  textTheme: ThemeData.light().textTheme.copyWith( 
  title: TextStyle( 
    fontSize: 20, 
    fontFamily: 'Lato', 
    fontWeight: FontWeight.bold, 
  ),),)

Я бы определил как:

const kStyleTitle = TextStyle( 
  fontSize: 20, fontFamily: 'Lato', fontWeight: FontWeight.bold, 
)
const Color kSliderColor = Color.fromARGB(0xff, 0xe1, 0x0c, 0x35);

TextStyle - это просто копирование и вставка из свойства стиля текстового виджета. Так что вспоминать особо не о чем.

Еще одно преимущество заключается в том, что файл констант содержит все используемые шрифты и цвета приложения в одном месте. С другой стороны, тема предоставит все стандартные настройки, а также, возможно, некоторые дополнительные настраиваемые свойства. Поэтому использование непреднамеренного стиля шрифта по умолчанию сопряжено с повышенным риском.

А как насчет производительности во время выполнения?

Я ожидаю, что простое использование константы требует меньше циклов процессора, чем поиск значения в дереве виджетов с помощью вызова Theme.of (context).

Так в чем же загвоздка?

После этого преимущества перевешивают, каковы недостатки глобальных констант?

Что ж - глобальные константы имеют запах кода. Это нелегко игнорировать.

Но: я думаю, что в каждой области очень важно знать, когда нарушать правила.

Есть несколько общих советов о нарушении правил на Medium. Например: 20 причин, почему нужно нарушать правила и Какие правила и когда нарушать.

Плохое изображение глобальных объектов в основном связано с двумя опасностями:

  • Нет никакого контроля над тем, были ли такие объекты изменены где-либо непреднамеренно.
  • Могут возникнуть непредвиденные конфликты имен, например, когда добавленный плагин или обновленная библиотека внезапно использует то же имя.

Первый риск на самом деле не существует, потому что, в конце концов, они константы. Их можно считать неизменными.

Остается второй риск. Однако в этом случае VS Code отображает очень полезное сообщение об ошибке.

В конце концов, для меня глобальные константы - это нормально. И есть еще несколько причин использовать глобалы без угрызений совести.

Причина номер один:

Библиотека flutter также предоставляет множество глобальных значений const.

Отсюда и возникла традиция начинать имена с буквы «k» в нижнем регистре.

Команда grep в Sublime Text приводит к 5 файлам с 35 совпадениями при поиске в файлах с именем constants.dart. И гораздо больше kName отображается во всплывающем окне Intellisense, когда вы вводите «k» и Ctrl + Пробел. Возможные значения варьируются от kA lwaysCompleteAnimation (определяется как global const в animations.dart) до kZ oomControlsTimeout в жестах / constants.dart.

Вторая причина для меня - это примеры кода Дейна Макки. Для меня он образец для подражания с большим опытом. Думаю, он очень тщательно подумал об использовании глобальных констант. Кстати: Его статьи на Medium и руководства на его веб-сайте просто великолепны!

И последнее, но не менее важное: Анджела Ю. Она дважды подумает, чтобы использовать глобальные константы при создании примеров своего курса. Это повлияет на многих будущих разработчиков флаттера. В своем примере приложения Flash-Chat она даже определяет полное оформление текстовых полей как константные значения.

const kTextFieldDecoration = InputDecoration( 
  hintText: 'Enter a value', 
  contentPadding: EdgeInsets.symmetric(
    vertical: 10.0, horizontal: 20.0), 
  border: OutlineInputBorder( 
    borderRadius: BorderRadius.all(
      Radius.circular(32.0)),
    ), 
  enabledBorder: OutlineInputBorder( 
    borderSide: BorderSide(
       color: Colors.blueAccent, width: 1.0), 
    borderRadius: BorderRadius.all(Radius.circular(32.0)), 
  ),     
  focusedBorder: OutlineInputBorder( 
    borderSide: BorderSide(
      color: Colors.blueAccent, 
      width: 2.0), 
    borderRadius: BorderRadius.all(Radius.circular(32.0)),
   ),
 );

или украшение тары:

const kMessageContainerDecoration = BoxDecoration( 
  border: Border( 
    top: BorderSide(
      color: Colors.lightBlueAccent, width: 2.0),
    ),
 );

Этот пример демонстрирует еще одно преимущество перед использованием темы: такие глобальные константы также могут использоваться для виджетов. Это имеет смысл, если они используются более одного раза.

Если вы не можете жить с глобальной константой

затем оберните их как статику в такой класс:

class Constants{ 
  String appName = "Flutter App"; 
  static Color lightPrimary = Colors.white; 
  static Color darkPrimary = Colors.black; 
}

и используйте их вместе с именем класса:

barColor: isDark ? Constants.darkPrimary : Constants.lightPrimary,

Я нашел это решение на github в источнике FlutterEbookApp от Фестуса Бабаджиде Олусегуна. Использование более подробное, но вы избегаете риска столкновения с уже существующими именами в глобальном пространстве имен.

Заключение

В этой статье просто сравнивались стандартные темы флаттера с глобальными константами. Я предпочитаю использовать коллекцию глобальных констант в одном файле, который я называю app_constants.dart.

Я думаю о сборе часто используемых констант из всех моих приложений в общий шаблон констант. По сравнению с набором фрагментов кода в редакторе эта коллекция значительно упростит запуск нового приложения.

BTW: На мой взгляд, можно рекомендовать и другие передовые методы, изложенные в статье Деррита.

Flutter - молодой и быстро развивающийся фреймворк. Время покажет, какие практики преобладают. Может быть, я замечаю преимущества тематики. Может быть, тематика лучше в действительно больших приложениях. Если у вас есть еще какие-то идеи, пожалуйста, добавьте свое замечание к моей статье. Добро пожаловать.

Спасибо Дэйну Маккеру и Деррику Мвити за их статьи о Flutter.