TGViewer
Flutter Friendly Flutter Friendly @flutterfriendly · 996 subscribers
Post #174 859
Привет, это Роза, Flutter Dev Friflex!😉

Недавно я решала задачу — нужно было валидировать файлы при загрузке и вызывать для них метод convert. Сложность в том, что у меня было 4-5 форматов, и со временем их могло стать еще больше.

Какие были варианты решения: 
☠️ if-case
Просто перечислить все форматы и вызвать нужный метод:

if (format == FileFormat.arb) {
  validateArb(file);
} else if (format == FileFormat.csv) {
  validateCsv(file);
}
// ...
// И это только validate, а еще есть convert...


В целом это будет работать, но немного отдает болью и будущими проблемами в виде сложно поддерживаемого кода. 
Добавить новый формат — +1  условие. 
Протестировать — сложновато. 
Расширять — ну такое.  

Использовать паттерн проектирования
Я решила, что Стратегия — то, что нужно.

Что говорит теория?
Стратегия — поведенческий паттерн, который:
▫️ выделяет семейство алгоритмов
▫️ выносит каждый из них в отдельный класс
▫️ делает их взаимозаменяемыми

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

В жизни часто можно столкнуться со стратегией: выбор способа оплаты (карта, наличные), выбор транспорта (метро, такси, автобус).

Вернемся к задаче
Я определила общий интерфейс FileConversionStrategy, который описывает, как работать с файлом:

abstract class FileConversionStrategy {
  bool supports(FileFormat format);
  FutureOr<ImportFileModel> convert(
    ImportFileModel file,
    List<String> editedResult,
  );
  void validate(ImportFileModel file);
}


Затем написала реализации под каждый формат. Например, ArbConversionStrategy:

class ArbConversionStrategy implements FileConversionStrategy {
  @override
  bool supports(FileFormat format) => format == FileFormat.arb;

  @override
  FutureOr<ImportFileModel> convert(
    ImportFileModel file,
    List<String> editedResult,
  ) {
    // логика конвертации
  }

  @override
  void validate(ImportFileModel file) {
    // логика валидации
  }
}


Каждая стратегия знает, как обрабатывать только свой формат. И вуаля — проблема решена! Теперь я могу добавлять сколько угодно новых форматов — достаточно просто написать для него реализацию FileConversionStrategy.

❕Но это еще не все. У нас есть реализации, но как выбрать необходимую в нужный момент?

Для этого я написала менеджер стратегий. Он перебирает доступные реализации и возвращает ту, что подходит:

class FileConversionStrategyManager {
  final List<FileConversionStrategy> strategies;

  FileConversionStrategyManager(this.strategies);

  FileConversionStrategy getStrategy(FileFormat format) {
    return strategies.firstWhere(
      (strategy) => strategy.supports(format),
      orElse: () => throw UnsupportedError('No strategy for format $format'),
    );
  }
}


А теперь разберем, как все это работает вместе:

1. Контекст — запрашивает подходящую стратегию и работает с ней через единый интерфейс
2. Интерфейс — объединяет все алгоритмы в общую структуру (validate, convert)
3. Конкретные стратегии — реализуют обработку разных форматов (CSV, ARB, JSON и других)
4. Во время выполнения мы подбираем нужную стратегию
5. Можно легко заменить стратегию на новую

Но применять паттерны ради паттернов — плохая идея. Их сила не в модности, а в том, что они решают конкретные проблемы.
Поэтому используйте стратегию:
✔️ Когда у вас разные сценарии поведения, и хочется вынести их из основного кода
✔️ Когда поведение часто меняется или дополняется
✔️ Когда хочется разделить ответственность и не мешать все в одном классе

Это уже третий паттерн. Здесь подробнее про:
🔗Observer
🔗Mediator
  • ❤ 9
  • 👍 5
  • 🔥 5
  • 💅 1
More from @flutterfriendly
  1. May 14, 2026👀Какой сложный вопрос или тема по Flutter вас сейчас беспокоят? Может, задача не идет, ба…
  2. Apr 17, 2026💭Привет! Это Роза, Flutter-разработчица Friflex! Уверена, многие из вас знакомы с Dart De…
  3. Apr 8, 2026Привет, друзья! Делимся нашей страничкой на Хабре, чтобы всегда оставаться на связи. Там е…
  4. Apr 3, 2026🌸Апрель в календаре и на экране Весна зовет обновлять визуальное: убирать темные темы и в…
  5. Apr 1, 2026Всегда с нетерпением ждем этого дня, чтобы сделать подборку ИТ-мемов Пусть поводов для улы…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →