Все верно, любой переиспользуемый код должен быть хорошо продуман. Любой подход, определяющий структуру приложения, должен быть задокументирован. Так и живём :)
Совершенно не надо гоняться за новыми фреймворками.
Однако если бы вы попробовали найти в 2020 году человека на саппорт проекта написанного на backbone или условном knockout вы бы ощутили большущую боль. Это одна из причин переписывания — тупо нет возможности найти людей на поддержку.
Равно как через
Никто не знает что выйдет из моды следующим. Рискну поставить на реакт хуки — как только фейсбук наиграется с этой радостью и перестанить её форспушить, отсутствие поддержки данного подхода вообще где-либо за пределами екосистемы реакта приведёт к отсутствию поддержки от комьюнити.
Есть и другие причины для смены фреймворка: уязвимости, недостаточная производительность.
Конкретно по вашему кейсу: реакт не фреймворк и что-бы написать «приложение на реакте» вам нужно подрубить к нему как минимум что то для управления состоянием и роутинга, а также определить желаемую структуру(расположение) кода. Эти задачи, за исключением роутинга, и решаются в статье. Я не придумывал и не пытался определить новый фреймворк. И мне жаль если статья создаёт ложное впечатление попытки увелечения ентропии в среде ФЕ разработки.
Честно — я сокращал и урезал как мог.
В итоге разделить просто не получалось — без первых разделов не понятна мотивация разделов 5/6/7. Без разделов 5/6/7 не понятно зачем лить воду в предидущих.
Роутинг не упомянут и не является частью статьи. Вы вольны использовать whatever suites your needs. В приведённом примере используется декларативный роутинг средствами react-router т.к. ради двух ссылок большего не надо. На последнем коммерческом проекте написанном в данном подходе роутинг реализовывался через интерфейс с методами navigate/buildNavigationLink для обеспечения строгой типизации роутов. Под капотом использовалась одна из популярных либ для того что-бы не изобретать велосипед для работы с history и для сериализации параметров запроса.
Запросы связываются с вью через вьюмодели. Т.е. любые данные, необходимые для вью, должны быть выставлены во вьюмодель (либо вьюмодель их должна запросить). В приведённом примере данные беруться из DAO обьекта (интерфейса), который реализован через localStorage. Если вместо локал стореджа хотим использовать апи — пишем новую реализацию интерфейса ITodoDAO, работающую с апи.
Нюанс который меня немного бесит: для того что-бы 1 в 1 приложение матчилось с классическим TodoMVC приложением я определил в ITodoDAO наличие синхронных методов. Они все, конечно же, должны быть асинхронными. Но повторюсь — в классическом TodoMVC асинхронности нет, а целью было сделать именно его, что-б можно было лоб в лоб сравнивать с другими реализациями.
Компиляция/сорсмапы и дев флоу не относятся напрямую к дизайну приложения и никак не влияют на переиспользуемость кода (ради чего собсно статья писалась).
Тем не менее: если вы посмотрите в пример на который ссылается статья — то увидите что компиляция делается роллапом, сорсмапы генерятся. Ничего необычного, но если будут вопросы — задавайте, буду рад ответить.
Кодогенерация при данным подходе просто не нужна, поскольку boilerplate отсутствует. Разработчик определяет вью и функцию среза в виде чистой функции, вьюмодель в виде обьекта. Для того что-б єто все «уселось» в иерархию компонентов дёргается две функции — withVM и connectXXX. Т.е. именно «кодогенерировать» просто нечего, и слава богу.
апд. вот подумалось что теоретически можно сделать команду для генерации вью и функции среза «одновремэнно» по пред-заданному интерфейсу пропсов. Подумаю об этом.
В целом плюс разработки «в рамках конкретного фреймворка» именно в том, что у разработчика есть много документации, от которой он может начать работать за условных 15 минут. Если нужно написать на коленке что-то что будет «просто работать сейчас» — то нечего парится подбором подходящей структуры, конечно.
Если же клиент заказал приложение которое будет жить дольше чем
Это недоработка примера от того что мне не нужна была данная возможность для реализации этого примера. А на продакшн проекте написанном в таком ключе эта возможность была нужна
Впрочем, мельком я на это ограничение в статье указал Посмотрим на синтаксис (в случае одной вьюмодели):
Но такие комменты стимулируют допилить, да.
Кстати любопытная статья, пойду обсуждать на медиум. Но джикверивский адаптер там просто невалиден и вводит в заблуждение, т.к. в отсутствие реактивности изменение данных никак не приведёт к изменению УИ.
Вуевский (это же вуй?) же в принципе должен быть жизнеспособен с той лиш разницей что на 89 слайде должна быть стрелочка от State к Domain. Стейт же хранит доменные обьекты и именно потому в принципе возможна перерисовка интерфейса. А эта стрелочка сразу же приводит к тому что каждый екшн стартует две ветви кода:
1) мутации стейта
2) изменения в доменных обьектах
Что видно из екшна makeMove (страница 99).
1) Сначала дёргается юзкейс, который изменяет состояние доменных обьектов.
2) А после этого кидается екшн «окончания действия» — фактически мутация. Который, subsequently, может привести к ещё одному изменению состояния доменных обьектов И/ИЛИ изменению стейта, не отрадженному в доменной модели.
Здесь нет принципиальной разницы с mvvm подходом, описанном в моей статье, т.к. метод вьюмодели, равнозначно екшну, может дернуть метод доменного обьекта и после этого дернуть ещё один метод той же вьюмодели.
Но моя статья и не пытается создать иллюзию того что взаимодействие с доменом полностью инкапсулировано в юзкейсах (или аппликейшн сервисах, называть можно как угодно). Не люблю ложные обещания типа «смотрите как можно» -> «вчитался» -> «ой, не можно». Вместо этого я определил механих функций среза, специально созданных что-бы ограничить доступ компонентов к функциям вьюмодели (в случае с наличием доменных обьектом — и к ним в том числе).
Спасибо за диалог!
По поводу завязки на мобх — статья и так получилась сложночитаемой из за обьёма. Мне хочется что-б у людей хватало headroom на чтение. Посчитав отвязку от мобх тривиальной задачей я решил не включать это в данную статью. Оставил на потом если будет интерес (вот вы оставили комментарий — видимо есть смысл сделать это «на потом»:)). Но это лирика и нюансы.
Что мне кажется важным в вашем комментарии это замечание о том что мы завязываем «доменный слой». Статья про реализацию слоя представления. Вьюмодели являются частью этого слоя, они служат цели «хранения обозреваемых данных для вью и инкапсуляции методов работы с ними, интеграции с доменными сервисами». Но это не доменные модели.
Использование доменных сервисов (и как следствие — доменных обьектов) подразумевается через внедрение их в конструктор вьюмоделей (DI). Реализация же доменных сервисов и обьектов может быть, а может и не быть реактивной. Это решение уже нужно принимать исходя из специфики приложения. Для TodoMVC создавать доменный слой было бы блажью и запутывало бы читателя («нафига оно здесь, почему так сложно?»).
Развернутый комментарий не для того что-б показать что «я тут самый правый» а потому что
несколько раз встречал проблемы из за того что разработчики ошибочно начинали дизайнить типа-как-слой-домена решая сугубо презентационные задачи. И как следствие — невероятное усложнение кода. Как написано в статье, бОльшая часть ФЕ приложений вообще не требует слоя домена: хватает елементарного хранения данных на вьюмоделях.
Лично мой подход: я начинаю дизайнить доменные обьекты когда в общении с заказчиком начинают всплывать термины и зависимости, не привязанные к конкретному УИ региону. Т.е. когда я вижу что бизнес мыслит некоторыми абстракциями категориями а не «крестик нажал — елемент из списка вышел вон».
зы. по декораторам: декораторы используются исключительно как метаданные, реально реактивность применяется функцией mobx.makeObservable туть (как раз благодаря механикам шестого мобикса). Переписывать придётся только если пропозал в принципе будет отклонён, а вместе с этим декораторы будут ещё и дропнуты из тайпскрипта. Вероятность такого события на мой взгляд околонулевая. Но теоретически это конечно возможно, да
Дякую, не бачив цієї статті. Лише пост в його блозі. Взагалі чудовий підхід. На початку розробки важко зрозуміти наскільки важко-підримуваним стає код структурований за технічною відповідальностю, а наприкінці розробки — вже запізно. Тому must read for everyone
Закон Парето в интерпретации Талеба — 64% работы делает 4% работников.
Автору, вероятно, пока что ещё не повезло побывать в обратной ситуации. Возможно так никогда и не повезёт (кто может знать). Но достаточно будет непродолжительного пребывания в обратной позиции что-бы исцелится от подобных мыслей и «принять».
«Delivery Manager»
«але то не точно»
шото у меня где то диссонирует не не могу сформулировать.
Если снять розовые очки и вытереть сопли радости со своего величия то профессия — профессия. Вы тут пришли деньги зарабатывать и делаете то что нужно бизнесу в продукте либо то что нужно деньгоимущему в сервисе. Хотите радужного кодинга — велком контрибутить в аутсорс. И да, даже там вы не застрахованы от фрустраций ибо в аутсорс тоже контрибутят не всегда от ума, а вот с code of conduct хош не хош приходится считаться иначе сраным веником из избы вон... Единственный реальный способ на 100% избежать фрустраций — писать свой собственный аутсорс с блекджеком и женщинами. Ну разве что от малообеспечености придётся пофрустрировать, но удастся это продать — жизнь удалась! (Эран Хаммер в помощь. He tried.)
Ну а если всё таки принимать работу как работу то не такая уж это и боль и едва ли страдания, знай себе решай логические головоломки пока с тебя пылинки сдувают. А иногда перепадают прям совсем лакомные куски и удаётся дать волю творческому потенциалу, но требовать такого изо дня в день? За деньги? Хм...
В реальности клиент не видит подобного со стороны подрядчика потому что энтузиаст вася делает работу за троих.
Собственно это одна из проблем решаемых в описанной структуре кода. Компоненты являются максимально тупыми и не хранят никакого состояния, жс в них используется исключительно для шаблонизации.