Журат Максим @ChessMax
Пользователь
Информация
- В рейтинге
- 3 436-й
- Откуда
- Россия
- Дата рождения
- Зарегистрирован
- Активность
Специализация
Mobile Application Developer
Senior
Flutter
Flutter Bloc
MobX
Mobile
Development of mobile applications
Пользователь
Ссылка на проект, который можно запустить, конечно, не помешала бы. Количество метаданных в примере с конструктором больше чем кода самого конструктора))
Оставшиеся 2 дня, так уж и быть, пока можно работать из дома...
В приведенном примере нет никакой динамической типизации. Рекорды в дарт строго типизированы. Если не указать тип, то компилятор выводит его автоматически. Это называется type inference.
Видимо имелось ввиду
Rx.combineLatest(...)
Exhaustiveness checking - это не синтаксический сахар. Синтаксический сахар - это когда, что-то можно сделать более удобно, чем раньше, при этом старый способ все так же работает. Exhaustiveness checking можно сделать только с помощью switch, никаких других вариантов нет.
Если мы убрали
dynamic
, то у нас нет никакой динамической типизации, как уже выше рассмотрели.Алгебраические типы данных это не только sealed классы.
Переменной нельзя присвоить тип, только значение. Pattern - это не выражение, так как его нельзя сохранить в переменной.
Текст не соответствует коду? В коде и репозиторий и блок создаются для каждого теста. При этом этот код еще и не соответствует коду в гитхабе.
Эти поля повторяются в трех классах? Может быть стоило вынести в какой-то базовый класс? Или миксин? В таком случае код геттера
emailStr
можно было бы значительно сократить. Еще момент в том, что во всех состояниях эти поля зануляемые, что странно. Блок как раз и славится тем, что позволяет безболезненно моделировать точные состояния.Конечно вкусовщина, но возможно стоило не создавать расширение, а перенести этот геттер прямо в класс `LoginState`? Кстати, если сохранить
this
в локальную переменную, то не придется писать `as LoginDataState`.Обычно для параметров и локальных переменных не используется знак подчеркивания
_
в названии, так как они и так приватные.Разве проверки одного только типа состояния достаточно? А вдруг в нем измененный эмейл не сохранится? Или сохранится не тот? Аналогично и в следующем тесте. Вдруг изменение пароля повлияло на ранее сохраненный эмейл?
Как то использование
seed
выглядит не очень уместным и даже опасным. По хорошему обычно изолируют зависимости, а в логику тестируемого класса извне не лезут. Другими словами лучше взаимодействовать с тестируемой сущностью только доступными публичными методами. Так как сделано ниже.По идее `
_bloc.add(EditedPassword('myPass123'));`
должно быть вbuild
, так как это относится к части arrange.Наверное так же стоило проверить случаи когда пароль и/или логин неправильные?
Запустил тесты из репозитория, но один не проходит:
Печалька...
Дважды на пустоту проверяется email, а пароль нет? Странно, что ваши тесты это не отловили. Возможно вам стоит посмотреть в сторону TDD?
Функция compute не кэширует результаты.
Спасибо, интересные нюансы. Не знал о них.
Было бы интересно узнать про отличия VCL от FireMonkey. А также плюсы и минусы последнего.
Ну главное, чтобы ребенку нравилось. Смысл идти, если не твое? Ну и если что, вернуться в где можно же?
Согласен.
Автор riverpod уже не однократно говорил, что с релизом макросов, riverpod будет их использовать. Интересно, останется ли возможность использовать riverpod без них? Подозреваю, что нет.
Строго говоря это не совсем так.
Спасибо за статью.
Вы переизобрели MobX) Читая статью думал, будет ли computed, но не увидел (жаль). На самом деле с пользовательской точки зрения это намного удобнее (хотя свои минусы тоже есть). Вместо кучи combineN и RebuilderN был бы один ComputedValue и Rebuilder. Потому, что постоянно указывать и менять цифры, прописывать для всего типы и все это вручную, ну такое... "Продать" относительно Stream и rxdart конечно получилось, но сравнивать, на мой взгляд, нужно не с ними, а с MobX и его аналогами, и возможно даже с Riverpod.
Строго говоря у
StreamController
-а нет методаdispose
.Сложно понять, что тут имеется ввиду. Видимо, то что вся изменения будут переданы в колбек? На мой взгляд такое редко нужно, и чаще всего это вычисления впустую и по умолчанию лучше вызывать колбек один раз и с последним значением.
Наверное лучше было бы использовать предикат? В таком случае возможности были бы шире.
Пример с
combine2
не компилируется. Зачем делать вCombinedValueSubscription
метод отмены с типомFuture
, если ассинхронность не используется?Если использовать тип
Either
, то можно не терять возможность обработки ошибок.Создавать новый экземпляр
Stopwatch
на каждый вызовnotify
несколько накладно.На использование микротасков должны быть какие-то веские причины, у вас много работы выполняется, т.е. это явно не должен быть микротаск, иначе привет подвисания, особенно на слабых устройствах. Настолько много, что вы даже замеряете время выполнения. Это не то что звоночек, это колокол!
Ну такое стоило сразу поправить, тем более, что это совсем не сложно сделать.
Очевидно, что transformer может быть накладен для вычисления, и лучше кэшировать значение.
Вы в нескольких местах что-то подобное пишете, но по факту это не совсем правильно. По-хорошему ваш
Value
так же должен предоставлять методdispose
или его аналог, т.к. во-первых, чтобы можно было отписаться от все подписок, с текущим апи это сделать нельзя. Во вторых наследники этого класса используют, напримерTimer
, который тоже никак не остановить, насколько я понял и он будет тикать, хотя уже может быть давно не нужен. Просто если тот жеStreamController
использовать по аналогии с вашими классами, то мы так же не обязаны вызыватьdispose
и будет плюс-минус такое же поведение, что и вас.В любом случае спасибо за вашу реализацию. Вполне перспективна, но явно требуются доработки (код привести в порядок, документацию, тестов исчезающе мало, но хорошо что вообще есть, с большой вероятностью много багов или не очень очевидного поведения, и т.д.). Я бы такое в таком виде продакшн не потащил.
То что есть порядок вычислений и не все считается, не говорит, о том, что таблица истинности не используется. Вот, например, есть выражение
a && b && c
. Мы вычислили значениеa
и оно равноfalse
. Воспользовавшись таблицей истинности и тем свойством, что считать все остальное не нужно вернули результат сразу. Оперировать таблицей в общем случае, это не значит, что нужно посчитать сначала все операнды. И вот здесь не соответствие между не оперирует, хотя на самом деле вполне оперирует. Мне кажется без таблицы истинности (явно или не явно) нельзя реализовать эти операторы, т.к. таблица истинности это и есть определение операции, просто в табличной форме, разве нет?Да это понятно. Просто фраза "не оперируют таблицей истинности" звучит странно (но может быть я не прав), как будто бы при вычислении она не используется, хотя она используется. И то что первый или второй операнды могут не вычисляется, это (опять, как мне кажется) не говорит, о том, что таблица истинности не используется. Это лишь говорит, что при вычислении выражения используются свойства логических операций, позволяющие не выполнять ненужных операций.
Можно вот этот момент разъяснить? Если результат совпадает, то это значит, что они оперируют таблицей истинности, разве нет? Или что здесь имеется ввиду?
Может быть подойдут сервисы по типу клавагонок ? Небольшой спортивный азарт, кастомизация машинок, все лучше "бессмысленного" (с точки зрения ребенка) перепечатывания текста с экрана? Кроме того можно тренироваться на своих текстах. Согласен, не идеально, но хоть что-то?
Спасибо за совет. Смотрю нескольких, но ощущение, что толку от этого нет. Своего рода развлекательный контент. Запомнить что-то малореально.
Вот это очень интересный момент. Тоже за собой такое замечаю. Задачи решаются относительно неплохо. А вот качество игры никакущее. И как это исправить не особо понятно. А что на ваш взгляд наиболее сильно влияет на улучшение именно качества игры в целом?
и
Мне кажется или эти фразы не стыкуются? Если деньги вас не мотивируют, то вам должно быть глубоко фиолетово на все эти цели и выполнили вы их или нет. Или я чего то не понимаю?
Подобрать хорошую задачу для тестового задания очевидно непросто. И так же очевидно, что эта задача явно не самый худший вариант для тестового (плюс в том, что не очень объемная задача и судя по всему из реальной жизни). С другой стороны я не уверен, что джун сам сможет справиться с ней (хотя может я и не прав). Ну а сеньору наверное вообще не стоит давать тестовое... (имхо).
Чтобы текст начал обрезаться нужно тексту задать ограничение по ширине (это легко проверить, засунув текст в
SizedBox
). Так же нужно понимать как работает лейаут уRow
/Column
. Оверфлоу возникает не у текста, а уrow
.Row
спускает unbound (от нуля до бесконечности) ограничения своим детям. Т.е. говорит тексту будь любых размеров, вне зависимости от ограниченийrow
(от шириныrow
). И если по итогу ширина текста превышает ограниченияrow
, то и происходит оверфлоу. Таким образом текст не обрезается из-за того, что отrow
пришли unbound ограничения. Вот и все. Крайне полезно разобраться с тем как работают лейаут и ограничения во флаттер (можно сделать по вот этой статье и своим экспериментам или чтением исходников). И тогда жизнь станет значительно проще)) Соответственно, если знаешь как эта система работает, то сделать так, чтобы она работала как тебе нужно обычно не сложно...