Pull to refresh
16
Karma
-1
Rating
Валерий @rookie_cruekie

Программист

  • Followers 19
  • Following 2

GetX for Flutter. Dependency Injection для частных случаев

А Вы попробуйте с малого, например, с obs/Obx - реактивных состояний.
Как говорится в оригинальной доке:

Если это ваша переменная:

var name = 'Jonatas Borges';

то, чтобы сделать ее реактивной, достаточно добавить obs

var name = 'Jonatas Borges'.obs;

и в UI для реактивного поведения, нужно всего лишь обернуть ее в Obx:

Obx(() => Text("${controller.name}"));

Никаких кодогенераторов, никаких стримбилдеров наружу, и прочего бойлерплейта. Вся сложность спрятана под капотом библиотеки. Такая лаконичность делает код прозрачным, легким для прочтения и понимания.

И самое главное, вам не надо идти на компромисс между чистотой и принципами ООП. К примеру, чтобы добиться инкапсуляции переменной, не требуется никаких ухищрений (спасибо @AndrewPiterov за решение):

// Делаем переменную приватной
final _name = 'Jonatas Borges'.obs;
// Навешиваем геттер
get name$ => _name.value;
// И сеттер
set name(String value){
  if(value.isNotEmpty){
    _name(value);
  }
}

и все. Реактивность UI не сломается, ничего вообще не надо менять. Obx(() => Text("${controller.name}")) по-прежнему останется реактивным, хотя в других местах кода можно использовать controller.name, как обычную переменную, ведь она таковой и является. Это решение очень изящно реализовано в коде библиотеки, там вообще стоит покопаться для развития.

RxDart: магические трансформации потоков

Да, Вы правы. Время идет, все меняется.

Создание, настройка и использование собственного Git-сервера

а подскажите, пожалуйста, как правильно приготовить на своем GitLab CI/CD? На родном-то я как-то не заморачивался, и подключил CodeMagic, он из коробки парсит проекты gitlab/github, а тут?

Зачем нам 170 разработчиков

А сколько разработчиков вам потребуется, чтобы наладить простейшую логистику, и не отменять заказ в последнюю минуту (я не шучу, именно так ваша автоматическая система и поступила)? Ужель курьер скончался прямо на пороге моего офиса?

Основы Dart Streams

Вот как раз по первой ссылке в моем ответе рассуждения и про отмену подписки тоже. Вкратце — все должно случаться само собою, но в ряде случаев в зависимости от архитектуры приложения может случаться ситуация подвешивания незакрытых ресурсов (типа файлов, других IO-потоков).
Поэтому я лично для себя всегда стараюсь закрывать, если это как-то связано с ресурсами. В простяцких случаях — нет, если не ругается линтер (все линтер-предупреждения я устраняю для верности).

Основы Dart Streams

Спасибо. Это перевод, к сожалению, автор прекратил публиковать серию.
По поводу же lambda, вот выжимка из официального Language Tour:


Most functions are named, such as main() or printElement(). You can also create a nameless function called an anonymous function, or sometimes a lambda or closure. You might assign an anonymous function to a variable so that, for example, you can add or remove it from a collection.

С этим термином изначально в программировании путаница. Кондовые математики конечно порвут рубаху за чистоту терминов, но в реальности lambda function, anonymous function, как-то стали означать одно и то же.

Основы Dart Streams

По мне так хорошим стилем будет всегда делать стриму cancel. В реальной жизни может оказаться, что поток, к примеру, управляет какими-то IO ресурсами, которые не вредно бы вовремя освободить. Делая завершение потока неизменным правилом, можно приобрести хорошую привычку.
Вот тут и тут можно почитать размышления на эту тему.

Flutter: локализация приложений средствами Android Studio

Спасибо, обязательно, вот только поизучаю новый плагин.

«RTFM, dude!», или как бесплатный сыр обошелся мне в $5. А мог бы и в $80+

Впору "Клуб Пострадавших" открывать. Реально вздрогнул, когда представил, сколько бы за месяц набежало.

«RTFM, dude!», или как бесплатный сыр обошелся мне в $5. А мог бы и в $80+

Ну, может быть. Я пока в это не вляпывался.

RxDart для самых маленьких… проектов

Удачи в работе. Надо быть ищущим, и любознательным.

RxDart для самых маленьких… проектов

Напрашивается аналогия с козой и баяном, если не забавнее.
Неоднократно доказано, что желание везде подстелить соломки не защищает от идиотов или любознательных вредителей.


Но раз уж Вы за чистоту рядов, то что скажете про реализацию toMap/fromMap в дарте "из коробки"? Отсутствие как минимум признака типа в карте делает ее худо-бедно применяемой только в узком локальном контексте, не позволяя передавать никуда дальше, ибо иначе может приводить к интересным коллизиям типа


test('Когда все пошло не по плану', () async {

    // в точке А.
    final manBefore = Straight(name: 'Serg', age: 25);
    final map = manBefore.toMap();
    print('man before is: ${manBefore.runtimeType} as $map');

    // в точке Б.
    final manAfter = Gay.fromMap(map);
    print('man after is: ${manAfter.runtimeType} as $map');

  });

LOG:
man before is: Straight as {name: Serg, age: 25}
man after is: Gay as {name: Serg, age: 25}

для схожих типов


class Straight {
  final String name;
  final int age;
   ...
class Gay {
  final String name;
  final int age;
   ...

и персонаж даже не узнает об этом, пока не нагнется за мылом....


Мир, он не черно-белый, и не становитесь упоротым адептом навязанных извне технологий, даже если очень надо или сильно хочется.

RxDart для самых маленьких… проектов

Давайте так, спасибо конечно, но мне тут не надо ничего расписывать, и так уже простыня-простынища.
Предлагаю Вам написать статью, в которой Вы представите свой взгляд. свои подходы, и свое видение.
Я достаточно знаю и про DI, и про BLoC, статья не об этом. Статья о том, что можно эффективно и просто достигать целей, используя очень простые решения. Я писал и с использованием Provider, и с использованием MVU, и в конечном итоге остановился на том, что безумное количество дополнительного кода не может служить оправданием того, что я использую хайповые решения. Видите ли, я сам себе режиссер, и мне не надо ходить на собеседование и ожидать тупых вопросов типа "а знаете ли вы вот эти стопицот модных технологий?", а в реальной жизни дауншифтинг на rxdart уменьшил мой код вдвое(!), не затронув производительность.


Вот о чем статья. Для сравнения технологий, практик, паттернов. Так что пишите свою, (и наполучаете от хейтеров в карму :) ).


PS. Да, вдогон. Про DI, Provider я вообще не упоминал, а на КДПВ указан концепт провайдера для BLoC, по аналогии с тем, что в этой статье. Пожалуйста, читайте статьи, которые комментируете, а не додумывайте свое за автора. Спасибо.

RxDart для самых маленьких… проектов

Прекрасно, когда есть из чего выбрать. Мне фломастеры из rxdart-коробки больше по душе, потому что я так или иначе последние три года пользуюсь ReactiveX в составе RxJava, RxQt, RxCpp в той или иной степени, с их подкупающей мощью обработки данных посредством цепочек операторов, и поэтому я убиваю двух зайцев, используя rxdart как управление состоянием UI и для работы с данными.

RxDart для самых маленьких… проектов

Ну, во-первых, насколько часто нам приходится писать счетчики? Начиная даже самый простой проект, потихоньку приходишь к усложнению. А вот представьте, Вам потребовалось вставить обратный отсчет для блокировки кнопки между нажатиями. Обойдетесь без фонового потока? А если нет, как будете реализовывать?
Позвольте представить решение в рамках концепции данной статьи:


/// делаем задержку в 3 секунды, с уведомлением через каждую секунду.
class _Counter {
  int _count;
  /// Счетчик обратного отсчета
  int _countdown = 0;

  int get count => _count;

  _Counter(this._count)
      : this.onCounterUpd = BehaviorSubject<int>.seeded(_count),
        this.onCountdownUpd = BehaviorSubject<int>.seeded(0);

  final BehaviorSubject<int> onCounterUpd;

  /// Евент обратного отсчета
  final BehaviorSubject<int> onCountdownUpd;

  /// Вынесем инкремент за пределы виджета, добавим генерацию события.
  Future incrementCounter() async {
    if(_countdown <= 0) {
      onCounterUpd.add(++_count);
      /// Запуск таймера, с вочдогом и генерацией евентов.
      _countdown = 3;
      onCountdownUpd.add(_countdown);
      Observable
          .periodic(Duration(seconds: 1), (_) => --_countdown)
          .take(3)
          .listen((e) => onCountdownUpd.add(_countdown));
    }
  }
}

после чего делаем FAB реактивным,


      /// Кнопка стала реактивной
      floatingActionButton: StreamBuilder<int>(
        initialData: _counter.onCountdownUpd.value,
        stream: _counter.onCountdownUpd,
        builder: (context, snapshot) {
          return FloatingActionButton(
            onPressed: snapshot.data <= 0 ? _counter.incrementCounter : null,
            tooltip: 'Increment',
            backgroundColor: snapshot.data <= 0
                ? Theme.of(context).primaryColor
                : Colors.grey,
            child: Icon(Icons.add),
          );
        }
      ), // This trailing comma makes auto-formatting nicer for build methods.

и добавляем рекативное же упоминание


            /// Реактивная надпись
            StreamBuilder<int>(
                stream: _counter.onCountdownUpd,
                builder: (context, snapshot) {
                  return Text(
                    'Rest ${snapshot.data} seconds',
                    style: Theme.of(context).textTheme.title,
                  );
                }),

RxDart для самых маленьких… проектов

Приходится повторяться специально для Вас, что мне не нравится раздутость кода, в которое обернуты оба решения, и я не применяю MVI в том виде, в котором он есть. Вы не вчитываетесь, а видимо, просто еще на утреннем автовзводе от общения в telegram.
Я бы с удовольствием увидел Ваши решения счетчика на BLoC, MVU, и сравнить количество строк, при одинаковом результате. Попробуйте принять, как данность, что это статься просто про другой подход к решению задач программирования. Пожалуйста. Спасибо.

RxDart для самых маленьких… проектов

Да я в курсе и нет, я не против. Каждый выбирает для себя. Я за стиль, простоту, изящество решений, по мне так этому всему отвечает именно ReactiveX. Он закрывает для меня почти все вопросы по взаимодействию и с View и между всеми слоями архитектуры с минимумом кода и максимумом выразительности. Это я еще не беру в расчет мощь его цепочек операторов.


Я честно наваял часть проекта на MVU, но потом убился о количество кода, которое надо добавлять. Да, можно было написать генератор, но код-то никуда бы ни делся и болтался, мозоля глаза, да и хороший генератор писать тоже надо дофига времени на отладку.


MVI я не использую в чистом виде по этой же причине, но мне импонирует immutable-way, и передача упакованного состояния в одном флаконе. Позже я черкану статью о своей реализации.

RxDart для самых маленьких… проектов

в процессе. Есть прикольная архитектура MVI, я ее применяю и в процессе слегка модернизирую. Вот спустя месяцок накидаю статью с реальным примером.

RxDart для самых маленьких… проектов

Да, согласен, косяк. Даже два.


  1. Поправимо
  2. Не отменяет самого принципа и эффективности применения
1

Information

Rating
Does not participate
Location
Екатеринбург, Свердловская обл., Россия
Date of birth
Registered
Activity