Приведи пример применения принципа DRY (Don’t Repeat Yourself) в Flutter.

Ответ

Принцип DRY направлен на устранение дублирования кода. Во Flutter его можно применять на разных уровнях.

1. Вынос повторяющихся стилей в константы или методы-хелперы:

// ПЛОХО: Стиль дублируется
Widget buildButton1() {
  return ElevatedButton(
    style: ElevatedButton.styleFrom(
      backgroundColor: Colors.blueAccent,
      foregroundColor: Colors.white,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
    ),
    onPressed: () {},
    child: Text('Submit'),
  );
}

Widget buildButton2() {
  return ElevatedButton(
    style: ElevatedButton.styleFrom(
      backgroundColor: Colors.blueAccent, // Дублирование
      foregroundColor: Colors.white,      // Дублирование
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), // Дублирование
      padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), // Дублирование
    ),
    onPressed: () {},
    child: Text('Cancel'),
  );
}

// ХОРОШО: Стиль вынесен в константу
const ButtonStyle myPrimaryButtonStyle = ElevatedButton.styleFrom(
  backgroundColor: Colors.blueAccent,
  foregroundColor: Colors.white,
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
  padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
);

Widget buildButton1() {
  return ElevatedButton(
    style: myPrimaryButtonStyle, // Переиспользование
    onPressed: () {},
    child: Text('Submit'),
  );
}

Widget buildButton2() {
  return ElevatedButton(
    style: myPrimaryButtonStyle, // Переиспользование
    onPressed: () {},
    child: Text('Cancel'),
  );
}

2. Создание кастомных переиспользуемых виджетов: Если у вас часто повторяется сложная композиция виджетов (например, карточка товара с изображением, названием и ценой), правильнее создать для нее отдельный виджет ProductCard. Это избавит от копирования одного и того же кода в нескольких местах и упростит будущие изменения дизайна.

3. Вынос бизнес-логики в отдельные классы (сервисы, репозитории): Вместо того чтобы писать один и тот же код для работы с API в разных ViewModel или Bloc, следует создать единый ApiClient или Repository и инжектировать его туда, где он нужен. Это классическое применение DRY на уровне архитектуры.

Ответ 18+ 🔞

А, слушай, смотри, вот этот ваш принцип DRY — это вообще святое, ёпта. По сути, он кричит на тебя: «Мужик, не повторяйся, блядь!» Если ты пишешь одно и то же в двух местах, ты уже накосячил. Это как рассказывать одну и ту же тупую шутку дважды — всем уже не смешно, а только раздражает.

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

1. Вынос стилей: не будь распиздяем.

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

// ПЛОХО: Ну ты посмотри на это безобразие. Овердохуища одинакового кода.
Widget buildButton1() {
  return ElevatedButton(
    style: ElevatedButton.styleFrom(
      backgroundColor: Colors.blueAccent,
      foregroundColor: Colors.white,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
    ),
    onPressed: () {},
    child: Text('Submit'),
  );
}

Widget buildButton2() {
  return ElevatedButton(
    style: ElevatedButton.styleFrom(
      backgroundColor: Colors.blueAccent, // Опять?! Да ядрёна вошь!
      foregroundColor: Colors.white,      // Серьёзно? Опять?
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), // Ну ёб твою мать...
      padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), // Терпения ноль, ебать!
    ),
    onPressed: () {},
    child: Text('Cancel'),
  );
}

Зачем это? Завтра дизайнер придет и скажет: «Хочу скругление 12 пикселей». И ты пойдёшь, как полупидор, ползать по всему коду и менять в каждом месте. Это же ебать копать, а не работа.

А теперь сделаем по-человечески, без мудни:

// ХОРОШО: Вынес в константу, и спокойно, как удав. Одна правка — и везде поменялось.
const ButtonStyle myPrimaryButtonStyle = ElevatedButton.styleFrom(
  backgroundColor: Colors.blueAccent,
  foregroundColor: Colors.white,
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
  padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
);

Widget buildButton1() {
  return ElevatedButton(
    style: myPrimaryButtonStyle, // Берём и используем. Красота.
    onPressed: () {},
    child: Text('Submit'),
  );
}

Widget buildButton2() {
  return ElevatedButton(
    style: myPrimaryButtonStyle, // Снова берём. И опять красота.
    onPressed: () {},
    child: Text('Cancel'),
  );
}

Видишь разницу? Теперь ты не копипастер, а адекватный разработчик.

2. Кастомные виджеты — твои лучшие друзья.

Если у тебя на экране пять раз повторяется одна и та же карточка с фото, названием и кнопкой «Купить» — это же крик души, ёпта! Не копируй этот блок раз за разом. Создай виджет ProductCard, засунь туда всю логику отрисовки и принимай данные параметрами. Это как взять и отлить одну деталь на заводе, а не вырезать её пять раз вручную из говна и палок. Доверие к такому коду — ебать ноль, но в хорошем смысле.

3. Логику — в отдельные сервисы. Не размазывай по всему проекту.

Это вообще основа основ. У тебя в трёх разных местах приложения нужно загружать список пользователей. Ты что, будешь в каждом Bloc или ViewModel писать один и тот же вызов http.get с одними и теми же заголовками и обработкой ошибок? Да ты сам от себя охуеешь через месяц, когда API изменится.

Создай класс UserRepository. Вынеси туда весь этот код. А потом просто инжектируй этот репозиторий туда, где он нужен. Одна логика — в одном месте. Изменил что-то в репозитории — и оно автоматически применилось везде. Это не магия, это просто не быть, извини, пидарасом шерстяным, который любит повторять одно и то же.

Короче, суть в чём: DRY — это про то, чтобы не изобретать велосипед каждый раз, когда тебе нужно доехать до магазина. Собрал один раз хороший, надёжный — и катайся на здоровье. А если где-то спустило колесо, чинишь в одном месте, а не бегаешь с насосом вокруг десяти одинаковых великов.