Почему мне нужно использовать расширения в моем проекте Flutter / Dart?
Вы не обязаны. Расширения - это способ сделать ваш код чище, и часто они просто синтаксический сахар. Однако, если вы можете упростить чтение и обслуживание, это, безусловно, стоит затраченных усилий и обязательно принесет вам и вашей команде ощутимые выгоды.
Как использовать расширения?
Вы используете расширения, когда хотите:
- добавить функциональность к существующему классу, но вы не можете изменить его напрямую, потому что он является частью внешнего API или библиотеки
- добавить методы в перечисление (например, в Java)
Синтаксис:
extension ExtensionName on Object { Object doSomething(Object arg1) { var result; //do operations... return result; } }
ExtensionName - это имя этого расширения, оно не является обязательным, мы делаем расширение для объекта, поэтому в этом случае мы можем использовать doSomething для любого класса Dart.
var str = 'Hello world!'; str.doSomething('arg1');
Пример # 1 - перечисление в String / перечисление из String
Проблема
Допустим, у вас есть перечисление
enum Animal { dog, cat, bird }
и вы хотите получить какой-нибудь объект Animal с сервера REST API.
Проблема, с которой я столкнулся, заключается в том, что ответ, который я получил от сервера формы, был в этой форме
{ "animal":"dog" }
и сервер принимает только значения, указанные выше, но форматы метода Dart toString () по умолчанию, такие как
print(Animal.dog.toString()); //prints Animal.dog
Поэтому мне нужно было другое решение, но я хотел избежать использования некоторых вспомогательных методов или добавления новых классов. К сожалению, в Dart нельзя писать методы для перечислений, как в Java, поэтому это был идеальный вариант использования для расширения.
Решение
Я создал двусторонние парсеры, чтобы легко общаться с сервером. Полный пример показан ниже.
Код объясняет сам себя, но в итоге позволяет мне легко анализировать перечисления полностью гибким способом.
Пример # 2
Проблема
Допустим, у вас есть метод REST, который принимает список идентификаторов пользователей и выполняет с ним некоторую операцию.
void deleteUsers(List<int> userIds) { //send to server... }
Это обычный случай, но когда вы всегда храните пользователей в списке объектов
class User { int id; String name; User(this.id, this.name); } var users = [User(1, 'Jack'), User(2, 'Emma'), User(3, 'James')];
вам нужно перебирать каждый элемент каждый раз, когда вы хотите вызвать метод, который принимает список идентификаторов в качестве параметра.
Решение
Чтобы сделать ваш код чище, вы можете создать расширение в Списке пользователей и использовать его везде, где вам нужно!
Полный код показан ниже:
Пример # 3
Проблема
Один из методов в моем API возвращал объект enum, но в форме массива int - число указывало, какое это значение перечисления.
Предположим, у нас есть перечисление из предыдущего примера.
enum Animal { dog, cat, bird }
сервер отправлял такое значение и принимал точно такую же форму
{ "animal":1 }
Решение
Расширения позволили мне упростить работу с этими числами. Все, что мне нужно было сделать, это убедиться, что порядок значений в моем перечислении точно такой же, как на сервере, поэтому числа
dog: 0, cat: 1, bird: 2
совпадают.
Пример # 4
Проблема
Простой пример: есть некоторые функции, которые вам нужно снова и снова использовать в своем коде, но на первый взгляд они кажутся слишком длинными и не очень понятными.
Решение
Я имел обыкновение расширять его, и это сэкономило мне несколько символов почти в каждом файле, что немного повлияло на удобочитаемость.
Пример # 5
Проблема
В моем приложении было много проверок, но вместо использования обычного решения - создания некоторого служебного / вспомогательного класса, я использовал расширения. Может быть, это не большая разница, но мне показалось немного проще.
Решение
Все примеры доступны на Github.