denisskin / todoapp Goto Github PK
View Code? Open in Web Editor NEWYa To Do Flutter Application
Ya To Do Flutter Application
Дай пожалуйста ссылку на apk
Readme: 0.5/1 - нет описания и скриншотов
flutter_lints: 1
форматирование кода: 1
Код разбит на фичи и слои: 1/2 - Код разбит на слои, но есть проблемы с тем, что поход в сеть лежит и вызывается в БД. Лучше такие вещи разделять
стейт-менеджмент: 2.5/5 - используется стейт фул виджет. Минус в том, что стейт берется прям из БД, то есть виджет завязан на дата слое. Лучше создавать отдельно стейт(хотя бы задать переменные) в виджете, который изменять в зависимости от дата слоя
косистентность: 3
релизована работа с бэком: 3
слой для бэка: 1/2 - Слой выделен в отдельный слой. Но сам класс похода в бэк предоставляет на прямую досуп в слой БД. И выходит, что слой бэка совсем не отделен от бд. Минусы такого подхода в том, что нельзя будет далать нормальные запросы напрямую в бэк не через БД.
реализована работа с бд: 3
слой для бд: 0 - БД на самом деле не выделен в отдельный слой. Мы на прямую обращаемся в БД из слоя презентации (виджетов)
Можно было бы выделить слой БД
Выделить слой для похода в бэк
Создать домэйн слой, который бы вызывал нужные методы у двух этих слоев
А сам виджет вызывал бы методы у домэйн слоя. Тогда виджет не был бы напрямую завязан на дата слое(это бд и бэк)
А также можно почитать про MVC или про MVVM такие паттерны помогут разобраться с разбиением на слои
работа с асинхроннкой: 1
интернационализация: 0 - ее нет
Привет! Сделано всё очень аккуратно и строго, выглядит тоже классно :)
Все совсем неплохо, только не сделана большая часть с Firebase и CI, из-за этого пришлось снять много баллов, к сожалению.
Твой проект у меня не собрался, так что оценивал по апк + смотрел код, конечно.
Если считаешь, что я где-то неправильно оценил, либо уверен, что ошибка только у меня - можешь писать мне в телеграм! @Kondraschov
Сумма баллов: 10
В принципе неплохое приложение получилось, но есть замечания.
Репозиторий на 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
), приложение не сохраняет состояния, сбрасывая количество задач к нулю. Если попытаться собрать приложение, то будет выведено следующее:
../../../../.pub-cache/hosted/pub.dev/device_info_plus-9.0.2/lib/src/model/android_device_info.dart:6:8: Error: Error when reading '../../../../.pub-cache/hosted/pub.dev/device_info_plus_platform_interface-7.0.0/lib/zmodel/base_device_info.dart': No such file or directory
import 'package:device_info_plus_platform_interface/zmodel/base_device_info.dart';
^
../../../../.pub-cache/hosted/pub.dev/device_info_plus-9.0.2/lib/src/model/android_device_info.dart:11:33: Error: Type 'BaseDeviceInfo' not found.
class AndroidDeviceInfo extends BaseDeviceInfo {
^^^^^^^^^^^^^^
../../../../.pub-cache/hosted/pub.dev/device_info_plus-9.0.2/lib/device_info_plus.dart:100:16: Error: A value of type 'Future<AndroidDeviceInfo>' can't be returned from an async function with return type 'Future<BaseDeviceInfo>'.
- 'Future' is from 'dart:async'.
- 'AndroidDeviceInfo' is from 'package:device_info_plus/src/model/android_device_info.dart' ('../../../../.pub-cache/hosted/pub.dev/device_info_plus-9.0.2/lib/src/model/android_device_info.dart').
- 'BaseDeviceInfo' is from 'package:device_info_plus_plaform_interface/model/base_device_info.dart' ('../../../../.pub-cache/hosted/pub.dev/device_info_plus_platform_interface-7.0.0/lib/model/base_device_info.dart').
return androidInfo;
^
../../../../.pub-cache/hosted/pub.dev/device_info_plus-9.0.2/lib/src/model/android_device_info.dart:40:14: Error: Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.
super(data);
^
Target kernel_snapshot failed: Exception
FAILURE: Build failed with an exception.
* Where:
Script '/home/master/snap/flutter/common/flutter/packages/flutter_tools/gradle/flutter.gradle' line: 1201
* What went wrong:
Execution failed for task ':app:compileFlutterBuildRelease'.
> Process 'command '/home/master/snap/flutter/common/flutter/bin/flutter'' finished with non-zero exit value 1
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 13s
Running Gradle task 'assembleRelease'... 14.1s
Gradle task assembleRelease failed with exit code 1
Что примечательно, если откатиться последнего комита до дедлайна (попробовать собрать приложение (homework#3 8131a4e), то там этой проблемы нет, как и тестов. Скорее всего проблема связана с пакетом device_info_plus.
Поскольку это может быть проблема с моей стороны, то за это душнить не буду, поскольку версия приложения из последнего коммита до дедлайна работает сносно как online, так и offline, хотя есть заметные подтормаживания. Да минусов и так много нашлось уже...
Не стоит хранить какие-то секреты (публичные ключи к доступу в БД и т.п.) открыто в публичном репозитории. Стоит почитать на счёт обфускации кода.
Советую присмотреться к одному из менеджеров состояний, поскольку данный вариант не стоит использовать, тем более в продакшене.
todoapp/lib/pages/home_page.dart
Lines 16 to 18 in 85c513f
Стоит поробовать декомпозировать код в home_page.dart
и task_page.dart
, скинув большую часть кода в подпапку widgets
.
Попробуй добавить локализацию, это поможет не харкодить множество слов, которые могут в дальнейшем измениться.
Множество документации есть, которые реккомендуют (а некоторые даже требуют, freezed к примеру), чтобы классы моделей были неизменяемыми (immutable), а изменения происходили через copyWith. Это действитель во много лучше, особенно это улучшает производительность приложения. Для простоты можешь воспользоваться пакетом кодогенерации freezed.
Не стоит обращаться напрямую к репозиторию из слоя pages. Будет лучше использовать некоторую "прослойку" между ними. Она помогает в дальнейшем рефакторинге кода. Зачастую этой "прослойкой" является менеджер состояний, которому ты просто посылаешь некоторые события, а уже он сам решает как поступать при определённом состоянии.
todoapp/lib/pages/home_page.dart
Lines 200 to 216 in 85c513f
Не могу сказать, что приложение плохое. Видно, что некоторые части делались впервые, и по многим критериям приложение проходит, но вот мой совет: попробуй выкрасть время, чтобы рефакторить код под некоторые критерии и паттерны (DI, SOLID, ...).
Не стоит прям переусердствовать, но в дальнейшем это поможет писать такой код, чтобы его было и легко понять, и также легко изменить. Может по времени немного укладываться не будешь, но зато ты всегда будешь уверен в той части кода, которую написал, и всегда будешь готов его дополнить/изменить, причём, что немало важно, без головной боли (сколько я таких проектов написал, что самому не по себе от только воспоминания о них, бррр).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.