Действительно ли расширение виджета является антипаттерном?
Я читал в паре мест, что расширение виджета Flutter - это антипаттерн. Это правда?
Я использовал подклассы виджетов, чтобы сократить вложенность, создав подкласс виджета, который я удаляю, и поместил его виджеты в его конструктор, например
class Foo extends FormBuilder {
Foo() : super (
// bunch of widgets here
);
}
Расширение виджета без сохранения состояния кажется более популярным, но оно добавляет к дереву еще несколько строк кода и виджет, что мне не нравится:
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FormBuilder(
// bunch of widgets here
);
}
Я читал, что возврат виджета из функции является антипаттерном, потому что он нарушает оптимизацию рендеринга . Есть ли у моего первого подхода также скрытые побочные эффекты? Т.е. действительно ли это антипаттерн?
Ответы
Расширение виджетов с отслеживанием состояния может привести к проблемам, поскольку их состояние типизировано для суперкласса, и вы не можете расширить их состояние, поскольку большинство классов состояний остаются закрытыми. Многие методы поиска, такие как BuildContext.findAncestorStateOfType()
.
Расширение виджетов без состояния должно работать в большинстве случаев, но, как вы уже заметили, не рекомендуется.
В целом, при всей реактивной и виджетной природе Flutter принцип композиции над наследованием - хороший образец для подражания.
Вы составляете из виджетов новые виджеты, новые виджеты, новые виджеты, новые виджеты ... Вы уловили суть.
Кроме того, вы сохраняете 2 строки кода, которые в основном генерируются автоматически, но вы лишаете себя всех простых помощников в VSCode / IntelliJ, таких как «Обернуть виджет с заполнением». Намного сложнее обернуть расширенный FormBuilder
отступ для всех случаев использования в вашем приложении. Если составить его несложно, просто заверните внутрь Foo
. То же самое и со всеми другими виджетами, которые вы используете для оформления тем, цветов, стилей шрифтов и т. Д. - отступы являются лишь примером.
Flutter - это скорее из composition
, чем Inheritance
. Но наследование с использованием StatelessWidget всегда будет полезно, когда родительские виджеты необходимо повторно использовать в дочерних.
Например:
class FormBuilder extends StatelessWidget {
Widget getWidget() {
return Text('Child Text');
}
@override
Widget build(BuildContext context) {
return Text('FormBuilder Text');
}
}
class Foo extends FormBuilder {
Foo() : super();
@override
Widget build(BuildContext context) {
return getWidget();
}
}
Итак, виджет, который вызовет виджет Foo () , дерево элементов виджета будет
- Фу
- контейнер
Если это нормальная композиция, тогда дерево элементов будет для этого
class Foo extends StatelessWidget {
Foo() : super();
@override
Widget build(BuildContext context) {
return FormBuilder();
}
}
- Фу
- FormBuilder
- текст
Нет ни одного официального документа, в котором говорится, что это плохой шаблон, но флаттер разработан с Composition
учетом. Итак, лично я никогда не наблюдал такой проблемы с производительностью или отставанием при наследовании, поэтому я бы посоветовал использовать Inheritance
это неплохой вариант.