#flutter #dart #service #wrapper
#flutter #dart #Обслуживание #оболочка
Вопрос:
Я хотел бы создать оболочку вокруг стороннего пакета Snackbar (сторонний Snackbar просто вызывается так: Get.snackbar(title, body, snackPosition: SnackPosition.BOTTOM);
), Чтобы отделить мое приложение от пакета и иметь возможность легко переключаться в другой реализации Snackbar.
Я полагаю, что это должен быть singleton по соображениям производительности. Я хотел бы назвать это как VpSnackBar(title, body);
в идеале. Я нашел, как создать синглтон в dart (Vp — это мой префикс приложения, чтобы определить, что он был создан в моем приложении):
Здесь я создал этот синглтон
class VpSnackBar {
VpSnackBar._privateConstructor();
static final VpSnackBar instance = VpSnackBar._privateConstructor();
static void show(String title, String body) {
Get.snackbar(title, body, snackPosition: SnackPosition.BOTTOM);
}
}
Я должен был бы назвать это как VpSnackBar.show(title, body);
. Но тогда я думаю, должен ли я просто создать простой класс со статическим методом, который будет делать то, что это делает, без создания экземпляра? Полезно ли создание экземпляра?
Другим вариантом является глобальная функция с именем в верхнем регистре, поэтому она используется как класс:
void VpSnackBar(String title, String body) {
Get.snackbar(title, body, snackPosition: SnackPosition.BOTTOM);
}
Это единственный способ, которым я знаю, как это назвать VpSnackBar(title, body);
. Какой мой предпочтительный способ его вызвать. Однако является ли глобальная функция плохой практикой? Могу ли я добиться вызова его как VpSnackBar(title, body);
без глобальной функции? Какой способ является наилучшей практикой?
Ответ №1:
Чтобы я мог быть в безопасности от любых потенциальных изменений в пакете
Вы не будете ни в коем случае.
-
Если владелец пакета решит полностью изменить внутренние компоненты метода, не касаясь его прототипа, эти изменения все равно повлияют на вас.
-
Если владелец пакета решит изменить прототип метода обратно несовместимым способом, который содержит критическое изменение, вы также будете затронуты этими изменениями.
Я полагаю, что это должен быть singleton по соображениям производительности.
Я вижу, что вы не запускаете никаких тяжелых процессов (например, ввода-вывода) при создании экземпляра вашего класса, поэтому я не понимаю, почему вы должны беспокоиться о производительности. Учтите, что для каждого build()
вызова виджета, который происходит много раз за одну секунду, создаются экземпляры сотен классов, и они не влияют на производительность приложения.
Однако является ли глобальная функция плохой практикой?
Вовсе нет. Реальная проблема с вашим подходом заключается в написании первой буквы функции с заглавной буквы. Это плохая практика, поскольку она заставляет читателя поверить, что вызов вашей функции на самом деле является вызовом конструктора.
Какой способ является наилучшей практикой?
Как я уже говорил, я даже не вижу разумного мотива для переноса snackbar в первую очередь. Но, оставляя этот вопрос в стороне, каждое из ваших решений кажется мне одинаково справедливым (до тех пор, пока вы не капитализируете первую из функций). В такой ситуации вы можете использовать тот, с которым вам удобнее.
Комментарии:
1. Я оставлю это в качестве комментария, поскольку это не по теме и очень самоуверенно: если вы заботитесь о хороших практиках,
get
немедленно прекратите использовать. Я мог бы написать целую статью о том, почему это ужасно плохо написано.2. Спасибо. Упаковка закусочной отделяет мое приложение от упаковки. Если я решу, что мне не нравится Get, я могу просто изменить свою реализацию snack bar в одном файле и сохранить контракт без изменений, а не засорять мое приложение. И я буду гораздо меньше подвержен влиянию их изменений в snack bar, если у них будут критические изменения, поскольку мне приходится иметь дело только с этими изменениями в одном файле. Мне также кажется неправильным не учитывать производительность, потому что якобы сотни классов создаются при каждой сборке, не влияя на производительность. По-моему, это звучит как опасное мышление.
3. Я понял вашу точку зрения о развязке, но вы должны учитывать, что Get работает с snackbar очень необычным способом. Например, если бы вы заменили snackbar Get на встроенную snackbar, ваш контракт не остался бы таким, какой он есть, потому что вам нужен
BuildContext
в качестве параметра.4. Я должен настаивать на том, что ваша забота о производительности не является необходимой. Это преждевременная оптимизация, поскольку вы не оценили, влияет ли это на производительность вашего приложения. На самом деле трудно сказать, имеет ли определенная оптимизация какое-либо значение. На самом деле, они могут даже ухудшить производительность. Это потому, что компиляторы делают много магии, а процессоры не работают интуитивно понятным способом. На таком высоком уровне программирования невозможно сказать, что определенная оптимизация выгодна без бенчмарка.
5. Это верно в отношении Get Snackbar. Get SnackBar слишком сильно отличается от Flutter SnackBar, так что их нельзя легко заменить друг на друга. Немного обидно. И правда, я никоим образом не повлияю на производительность отрицательно в этой задаче.