Ответ
DRY (Don't Repeat Yourself — «Не повторяйся») — это фундаментальный принцип разработки ПО, который гласит: «Каждое знание должно иметь единственное, однозначное, авторитетное представление в системе». На практике это означает устранение дублирования логики, стилей или структуры кода.
Проблема дублирования в Flutter-проекте:
// ❌ Нарушение DRY: одинаковая стилизация кнопки в разных местах
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
child: Text('Save'),
)
// ... и тот же самый стиль повторяется для кнопки 'Submit', 'Confirm' и т.д.
Решения в соответствии с DRY:
-
Вынос в константу или метод:
// ✅ Единый источник стиля final ButtonStyle myPrimaryButtonStyle = ElevatedButton.styleFrom( backgroundColor: Colors.blue, foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ); // Использование ElevatedButton(style: myPrimaryButtonStyle, onPressed: () {}, child: Text('Save')), ElevatedButton(style: myPrimaryButtonStyle, onPressed: () {}, child: Text('Submit')), -
Создание кастомного виджета:
// ✅ Кастомная кнопка с инкапсулированной логикой и стилем class PrimaryButton extends StatelessWidget { final String label; final VoidCallback onPressed; const PrimaryButton({super.key, required this.label, required this.onPressed}); @override Widget build(BuildContext context) { return ElevatedButton( onPressed: onPressed, style: myPrimaryButtonStyle, // Используем константу из примера выше child: Text(label), ); } } // Теперь изменение стиля всех кнопок происходит в одном месте. -
Использование тем (Theming) в Flutter:
// ✅ Глобальное определение в ThemeData MaterialApp( theme: ThemeData( elevatedButtonTheme: ElevatedButtonThemeData( style: myPrimaryButtonStyle, ), ), );
Почему DRY критически важен:
- Снижает количество ошибок: Исправление или улучшение логики требуется только в одном месте.
- Упрощает поддержку: Код становится чище и понятнее.
- Повышает согласованность: UI и поведение приложения единообразны.
Осторожно: Слепое следование DRY может привести к излишней абстракции и сложным зависимостям. Иногда небольшое, осознанное дублирование («прагматичное дублирование») лучше, чем неправильная абстракция.
Ответ 18+ 🔞
Давай разберем этот ваш принцип DRY, а то смотрю — народ как обезьянки, один и тот же код копирует, а потом охуевает, когда надо в ста местах правки вносить. Ёпта, ну вы даёте.
Смотри, суть проще пареной репы: «Каждое знание — один раз и в одном месте». Представь, что у тебя в коде как в плохой коммуналке — один сосед (кусок логики) рассказал анекдот, второй его пересказал криво, третий вообще забыл концовку. И когда оригинал меняется, начинается пиздец и волнение ебать. Все сидят с разными версиями. DRY — это выселить всех в отдельную квартиру и поставить на стену один общий телевизор с актуальной новостью.
Вот тебе наглядный пиздец в проекте на Flutter:
// ❌ Нарушение DRY: пиздец как не надо делать. Один и тот же стиль кнопки раскидан везде.
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
child: Text('Save'),
)
// ... и этот же уёбищный стиль ты встретишь ещё в двадцати файлах. Полный распиздяй.
Как по-человечески решить, чтобы не было мучительно больно:
-
Выкинул в константу — и спи спокойно.
// ✅ Один источник правды, один хозяин. Меняешь здесь — обновляется везде. final ButtonStyle myPrimaryButtonStyle = ElevatedButton.styleFrom( backgroundColor: Colors.blue, foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ); // Использование — красота, а не код. ElevatedButton(style: myPrimaryButtonStyle, onPressed: () {}, child: Text('Save')), ElevatedButton(style: myPrimaryButtonStyle, onPressed: () {}, child: Text('Submit')), -
Заверни всё в свой виджет — вообще красота.
// ✅ Кастомная кнопка. Всё зашито внутри, снаружи только текст и действие. class PrimaryButton extends StatelessWidget { final String label; final VoidCallback onPressed; const PrimaryButton({super.key, required this.label, required this.onPressed}); @override Widget build(BuildContext context) { return ElevatedButton( onPressed: onPressed, style: myPrimaryButtonStyle, // Берём ту самую константу child: Text(label), ); } } // Теперь хоть завтра дизайнеру в голову ебнет поменять все скругления — ты поправишь в ОДНОМ месте и ни о чём не забудешь. -
Если проект большой — тема твой лучший друг.
// ✅ Глобально прописал в теме — и все кнопки в приложении стали послушными. MaterialApp( theme: ThemeData( elevatedButtonTheme: ElevatedButtonThemeData( style: myPrimaryButtonStyle, ), ), );
А зачем этот весь цирк, спросишь?
- Меньше косяков: Баг пофиксил в одном месте — он автоматом чинится везде. Никаких «ой, я же забыл в том файле поправить».
- Поддержка — не ад: Приходит новый разработчик, смотрит — а, стили кнопок вот тут лежат. А не бегает, как угорелый, по всем экранам.
- Всё единообразно: Приложение не выглядит как солянка из кусков, сделанных впятером в слепую.
Но! Тут главное — не перестараться. Иногда видишь, как человек ради DRY создаёт такую ебанутую абстракцию с кучей условий и параметров, что проще было десять раз скопировать. Это уже не принцип, а пиздопроебина. Иногда немного осознанного дублирования лучше, чем кривая, насильственная абстракция. Чувствуй грань.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶