Open leshhub opened 1 year ago
Из того что я заметил:
Readme.md
по сути пустой. Когда описаны фичи и проделанная работа, гораздо проще проверять работу и оценивать конкретные пункты.main.dart
, а после runApp, например, в initState'e HomePage
. Это связано с методом getInstance
в shared_preferences.
https://github.com/denisskin/todoapp/blob/85c513f56131ce846953ef505c101af880b89e92/lib/providers/db.dart#L100-L110TextField
для быстрой возможности добавить таску. Я и сам по началу думал, что это просто вторая кнопка на окно редактирования.windows
, linux
, macos
). pubspec.yaml
и analysis_options.yaml
https://github.com/denisskin/todoapp/blob/85c513f56131ce846953ef505c101af880b89e92/pubspec.yaml#L3-L4
https://github.com/denisskin/todoapp/blob/85c513f56131ce846953ef505c101af880b89e92/analysis_options.yaml#L1-L2
Понравился дизайн иконки.
В принципе неплохое приложение получилось, но есть замечания.
Критические замечания.
Репозиторий на GitHub-e (или любом другом Git-репозитории) - лицо приложения. Оно должно содержать в полном объёме:
За оформления пол балла заберу. Не потому что я такой душнила или злюка (;⌣̀_⌣́), так человеческий мозг устроен, который любит картинки, а не текст, а также любит пользоваться тем, у чего есть подробнейшее описание. Стоит сразу практиковаться оформлять свой проект.
Нет чётко-организованного менеджера состояния. Для его реплизации можно было бы воспользоваться разными фреймворками (BloC, ChangeNotifier, ...), но постоянное обновления состояний через
setState((){})
- это плохо.Думаю тут и так понятно, что нет DI, уж слишком всё друг от друга зависит. К тому же, тесты производятся над реальными данными, что плохо.
Если кратко, то DI - это паттерн, который подразумевает, что если компонент зависит от какой-то внешней сущности (виджет завит от менеджера состояний, который зависит от внешних репозиторий), то в таких случаях просто можно передать ему эту зависимость, через которую он и будет обращаться. Тем самым, компонент перестаёт получать "неконтролируемый доступ" во внешнюю среду (снаружи компонента).
Если видишь, что компонент (или просто файл) лезет куда-то в наружу (не через библиотеку), то стоит попробовать эту зависимость прокинуть через параметры, если это конечно необходимо (т.е. без фанатизма подходить к данному паттерну).
Не реализован интеграционный тест. Да, присутствуют widget-тесты, но интеграционный следовало сделать отдельно. Он должен запускаться на реальном устройстве, а не на виртуальном, как это происходит в widget-тестов. Здесь подробно описано о том, как это можно сделать.
Используется Navigator 1.0, а не 2.0. Стоит присмотреться к
go_router
. И соответственно нет реализации deeplink-ов. На самом деле в нём (go_router
-e) нет ничего сложного, его очень легко интегрировать заместо navigator 1.0. Есть даже кучу гайдов по переезду между ними. Подробнее проgo_router
можно почитать здесь. Главное не делай как было в лекции (там ересь) (>m<);Работа приложения без интернета невозможна. При установке apk (который лежит в дириктории
dist
), приложение не сохраняет состояния, сбрасывая количество задач к нулю. Если попытаться собрать приложение, то будет выведено следующее:Что примечательно, если откатиться последнего комита до дедлайна (попробовать собрать приложение (homework#3 8131a4e), то там этой проблемы нет, как и тестов. Скорее всего проблема связана с пакетом device_info_plus.
Поскольку это может быть проблема с моей стороны, то за это душнить не буду, поскольку версия приложения из последнего коммита до дедлайна работает сносно как online, так и offline, хотя есть заметные подтормаживания. Да минусов и так много нашлось уже...
Замечания (не в зачёт, просто на заметку):
Не стоит хранить какие-то секреты (публичные ключи к доступу в БД и т.п.) открыто в публичном репозитории. Стоит почитать на счёт обфускации кода.
Советую присмотреться к одному из менеджеров состояний, поскольку данный вариант не стоит использовать, тем более в продакшене. https://github.com/denisskin/todoapp/blob/85c513f56131ce846953ef505c101af880b89e92/lib/pages/home_page.dart#L16-L18
Стоит поробовать декомпозировать код в
home_page.dart
иtask_page.dart
, скинув большую часть кода в подпапкуwidgets
.Попробуй добавить локализацию, это поможет не харкодить множество слов, которые могут в дальнейшем измениться.
Множество документации есть, которые реккомендуют (а некоторые даже требуют, freezed к примеру), чтобы классы моделей были неизменяемыми (immutable), а изменения происходили через copyWith. Это действитель во много лучше, особенно это улучшает производительность приложения. Для простоты можешь воспользоваться пакетом кодогенерации freezed.
Не стоит обращаться напрямую к репозиторию из слоя pages. Будет лучше использовать некоторую "прослойку" между ними. Она помогает в дальнейшем рефакторинге кода. Зачастую этой "прослойкой" является менеджер состояний, которому ты просто посылаешь некоторые события, а уже он сам решает как поступать при определённом состоянии. https://github.com/denisskin/todoapp/blob/85c513f56131ce846953ef505c101af880b89e92/lib/pages/home_page.dart#L200-L216
Заключение
Не могу сказать, что приложение плохое. Видно, что некоторые части делались впервые, и по многим критериям приложение проходит, но вот мой совет: попробуй выкрасть время, чтобы рефакторить код под некоторые критерии и паттерны (DI, SOLID, ...).
Не стоит прям переусердствовать, но в дальнейшем это поможет писать такой код, чтобы его было и легко понять, и также легко изменить. Может по времени немного укладываться не будешь, но зато ты всегда будешь уверен в той части кода, которую написал, и всегда будешь готов его дополнить/изменить, причём, что немало важно, без головной боли (сколько я таких проектов написал, что самому не по себе от только воспоминания о них, бррр).