Хорошее видео для общего понимания Я бы не привязывался к количеству строк в классе для разбиения. Главный принцип здесь - SRP. Если есть решение у команды использовать clean architecture, юз кейсы - будь добр использовать это во всех вью моделях и не тратить свои и ревьювера ментальные ресурсы на принятие решения. Потом класс разрастается и что - надо рефакторить, тесты переписывать. Проще изначально сделать правильно
Сразу видно, что видос прям о наболевшем) Еще бы это донести до тех аутсорс компаний, которые делают приложения и забывают про них, но надо обязательно упороться в "архитектуру", написать кучу лишнего и ненужного, чисто для того, чтобы показать мол видали, мы пишем "правильно"
@@aleksandrvolkov4310 Надо понять одно, автор просто забыл упомянуть, архитектура приложения это ни что-то незыблемое, а она так же должна развиваться с ростом проекта. Как пример, на другом канале рассказали про правило трех, когда у вас есть какой-нибудь метод в одном месте, вы можете смело его скопировать в другое, может слегка изменить. Но вот если это приходится делать в третий раз - это повод задуматься о выделении данного метода в отдельный класс и переиспользовании. Архитектура - это живая сущность, растет вместе с проектом и должна отвечать только тем требованиям, которые существуют на данном этапе.
По поводу выбора архитектуры я всегда вспоминаю одно наше приложение. В один прекрасный момент один наш постоянный клиент просит нас написать приложение-логинилку. Т.е. ты сканируешь QR код, отправляешь запрос на бэк и происходит какое-то действие. Например логин в системе или открытие электронного замка. Не вопрос. Я пишу его за пару дней и мы довольные расходимся. Проходит немного времени и выясняется, что нужно еще показывать статистику приходов на работу после логина. Запросто. А потом менеджеры очень запросили выводить статистику по процессам. И каждый раз звучало что-то из серии "вот это вот и все". Примерно первый год. Сейчас это CRM с SIP телефонией, чатами и целой кучей функционала. Изначально я закладывал архитектуру с избытком по отношению к функционалу. Как же сильно я в тот момент ошибался ;)
От себя ещё накину, что любые правила, типа "если класс занимает больше N строк, то его нужно разбивать" конечно стоит держать в голове, но действовать все равно по ситуации. Если ваш класс хорошо согласован, не делает ничего лишнего, то пусть он занимает хоть 800 строк, вполне может быть так, что от разбиения код станет только запутаннее.
Поддерживаю мысль что нужно делать только то что нужно, а что не нужно не делать) Но с примером 19:08 когда отдельные модули делать не совсем согласен, в большинстве случаев над модулями начинают думать не когда команды параллельные есть, а когда твой монолитный модуль собирается минуту+ и это всех начинает напрягать. Главная их фича в том что и инкрементальный и клин билды намного предсказуемее работают, из-за чего проект можно скейлить и параллелить (А проблемы со временем сборки начинаются очень быстро, даже каких-нибудь 100к строк кода с каптом уже достаточно чтобы начать их ощущать). Так что это скорее про грэдл и котлин, и то как они устроены, а не про команду. И даже более того, если "эта параллельная фича тима" будет просто жить в отдельном модуле без правильного контракта, то она зааффектит сборку гораздо сильнее чем если бы они писали всё в том же монолите, потому что перед монолитом теперь надо их модуль целиком собрать. Я бы тут сказал скорее "не лезте создавать модули если не понимаете к каким последствиям это приведёт, лучше монолит чем плохая модуляризация".
Лайк! Но про 600 строк хз, как по мне это слишком много для андроид проекта. Уже после 300-400 возникает чувство что что-то не так и SOLID где то умирает в сторонке)
Делай как удобно, кажется это основной посыл видоса, мне например нравится закрывать классы интерфейсами (не все подряд очевидно) но если закрывать условную репу интерфейсом, так проще ориентироваться что есть внутри нее, просто почитал контракт с репой и погнал ее использовать (про многомодульность и тестирование тут не говорю)
Про интерактор, мне кажется стоит обратиться к первоисточнику th-cam.com/video/Nsjsiz2A9mg/w-d-xo.html. Потому что ваше объяснение ему не соответствует и только путает. Поправьте, если я что-то не знаю про Viper, но насколько мне известно, то там интерактор имеет абсолютно тоже значение что и в clean architecture. Интерактор - это объект реализующий сценарий использования.
Круто, согласен полностью и обеbми руками, ногами за каждое слово. Но только вот, еще бы на собесах от Junior не требовали бы clean architecture. Я конечно понимаю, что Junior должен хотя бы представлять, что это такое и на проекте не донимать вопросами дядей Seniors, что это такое и зачем. Но блин порой из-за дефицита кадров(Или жадности работодателей, все хотят за дешево спеца и сразу "херак-херак" продакшен) реально на позицию junior ищут midlle. И в итоге начинают делать pet проекты на 1-2 экрана с clean archeteture. Дабы показать, что они её знают, хотя она там нафиг не уперлась. Да и пониманию её, это ну ни разу не способствует:(
1) Почему то про модули не сказал для ускорение сборки, на огромных проектах без разделения невозможно. 2) Про архитектуру в общем: если убрать тестирование, то она нужна для понимания проекта новым человеком. 3) Нужен ли обязательно домен слой(если нет какой-то бизнес логики, просто сходи в сеть и покажи результат), вопрос очень холиварный. В частности надо ли делать маппинг даат классов на каждом слое, иначе api response ответ, объявленный data слое будет виден в presentation, что не по клину)) 4) Ещё бы добавить в видео пару слов о архитектуре, которая используется в гугловых примерах и кодлабах, многие берут оттуда, считая это эталоном.
Интересное видео. У себя пришел к тому, что в 80% случаев в MVVM мне требовались только репозитории и в 20% - usecases к ним. Причем логика в usecase очень хорошо выделяется в процессе развития проекта, и изначально их плодить на каждый чих точно не стоит. Но не совсем согласен с запретом использования одного usecase из другого (горизонтальные зависимости) - если у них адекватное именование и взаимодействие внутри usecase логично и понятно, считаю, что не зачем городить еще один уровень абстракции создавая Interactor.
Функция в 50 строк? На мой взгляд, это до хера. 10-20 строк максимум, функция должна делать только одну логическую операцию если иначе, то ее необходимо разбивать на ряд малых фукций.
Я считаю если ты начинающий, "особенно начинающий" то архитектуру с юзкейсами и тд нужно пихать даже в калькулятор! Даже если ты не планируешь идти в команду, даже если это твое хобби от основной работы и ты не планируешь серьезно лезть в mobile development всегда везде следует делать архитектуру. Почему? Потому что должна вырабатываться привычка писать чистый читаемый код, это как в спортзале: если ты привык одевать пояс на присед с малым весом (допустим 30 - 50 кг), у тебя не будет проблем когда ты будешь приседать 90 - 120 ты первым делом автоматом будешь искать пояс потом только выполнять упражнение (безопасность превыше всего!). Еще пример: гораздо проще накидать юзкейсов и потом по ним продвигаться, чем сидеть и думать что тут должно быть или что тут еще можно добавить... я раньше не понимал подход database first типа "что за бред" 🤔, сейчас же наоборот, к UI перехожу в самую последнюю очередь когда все разложено "по полочкам" по пакетам по юзкейсам.
9:54 а как же тестирование наших датасорсов, подмена реализации. может быть, на одном скрине нам нужно сохранять данные A , а на другом мы хотим сохранять данные B . Вы предлагаете скопипастить DataSource для сохранения A , чтобы создать DataSource для хранения B ? тогда нарушается DRY . или нам нужно перед сохранением данных B удалять данные A , тогда это можно решить паттерном декоратор))
Благодарю за видео. Единственное не понял почему плохо, чтобы юз кейс использовал другой юз кейс. Например я в приложении работаю на одном экране со списком сущностей1, а на втором экране со списком сущностей2. Сущность1 хранит в себе список сущностей2. Сущность2 хранить в себе список сущностей3. Если использовать в юз кейс только репозитории, то возникает дублирование кода при сборке сущности2.
Горизонтальные зависимости плохи тем, что сегодня мы в UseCase1 добавляем зависимость от UseCase2 и у нас все вроде ок, а завтра оказывается что нам в UseCase2 нужна зависимость от UseCase1, и вот мы уже не можем пользоваться inject конструкторами даггера, потому что появляется циклическая зависимость (т.к. мы не хотим иметь несколько инстансов одного и того же юзкейса). В вашем случае если сборка сущности2 слишком сложная, то можно ее вынести в какой-нибудь отдельный делегат, и его инжектить в каждый юзкейс
Привет, как тебе идея позвать на видео или стрим кого-нибудь из команды Language Design, и поговорить с ним о будущих дизайн фичах котлина, чем они сейчас занимаются, над чем больше всего работают и тд. Я думаю это будет оочень интересно
разбиение функций и классов должно быть конечно не по длине в строках, ибо длина в строках сильно зависит от особенностей конкретного языка и используемых конструкций, а в зависимости от цикломатической сложности и вообще здравого смысла. Т.к. функция или класс должны выполнять какое-то одно действие или быть расчитаны на одного актора, то это логически не позволяет классу или функции быть слишком большими, ибо они тогда начинают делать еще доп действия, которые они делать не должны
14:04 а что если есть бизнес логика отображать моментально на юай обновление Вьюхи после действия юзера , результат выполнения которого требует времени (запрос в сетку) , то здесь как по мне идеально подойдёт вложенный интерактор в другой интерактор, отвечающий за запрос в реальную сетку.
8:30 жертвуем увеличением количества кода. на клине приходится писать в разы больше и код под задачу будет размазан по нескольким файлам, а не по одному
Скажите, пожалуйста, по поводу тестового задания для джуна. Если задание стандартное вроде 2х экранов список + детали, то делать всё по clean(слои, интерфейсы, мапперы) - это в плюс идет или в минус?
Меня бомбит от джунов и мидлов, которые MVP на MVVM натягивают и Clean архитектурой все это погоняют, но при этом не знают фундаментальных вещей по типу чем List от Set отличается. А еще часто задаю очень простой вопрос на собесе: зачем нужна архитектура. И многих людей это ствит в тупик. И там идут ответы "Ну так надо" или "Все так делают"
Спасибо за интересное видео. Но я не совсем понимаю почему горизонтальные зависимости плохи по вашему мнению? На мой взгяд когда для вычисления чего-то в юзкейсе нам нужен результат другого юзкейса - использовать его можно и нужно. Или вы считаете что лучше поставлять результаты других юзкейсов параметрами? Хотелось бы поимер ситуации когда вложенность юзкейсов вредит, а не помогает.
Немного не понятно в мобильной разработке. Нашёл круг A Comparison of Popular Flutter App Architectures (ui, web, db, external, interfaces, devices) внутри (controllers, gateways, presenters) внутри (use cases, entity) чем это связано с application layer (presentation, business logic, data access) и MVC, MVP, MVVM? В вебе всё делится на front end например angular(module->component->service->rest api) и back end например nest js (http request->controller->dto->service->dto->repository->entity->db) если не брать (Firebase как альтернативу) , а в мобилах всё вместе нету разделения на front и back? Ну хотя смотря какой вид рендеринга CSR(spa), SSR, SSG, LSR, RSC
О нашёл ios, swift clean arhitecture with MVVM Ui (view) , View model - presentation layer (MVVM) UseCase, interactor, entity - domain layer (business logic) Repository, data source, api/storage service - data layer (data repositories)
Не согласен в деталях, да архитектура должна соответствовать масштабу проекта, но она всё равно должна быть, можно не использовать интеракторы/юзкейсы, но разбиение на модули и следование гайдам очень важно, тк во первых читаемость, расширяемость хорошая, и разделение ответственности автоматически, (+ интерфейсы лучше применять, и di и тестирование проще с ними) во вторых - в будущем на проекте будут работать другие люди, и они быстрее вьедут и не будет вопросов "че тут за говнокод". Плюс польза для самого себя - ты сразу заводишь привычку писать всё нормально, в итоге нет каши в голове типа "а надо тут или нет" - просто делай сразу нормально, и переделывать потом не надо будет, переделки множат говнокод и разнообразие в проекте, а хорошая архитектура - это минимум разнообразия в подходах. В больших проектах часто такое вижу, что модули сильно отличаются по реализации, надо пытаться минимизировать эту разницу
Помниться написал на PHP форум , с модерацией и т.д , там не то что клин архитектуры не было , там даже ООП не использовалось . Ни одного класса . Долго не мог понять зачем вообще эти классы нужны .
Интересует как в случае клин архитектуры передавать токен в ретрофит. У последнего есть хорошая вещь для этого - интерцепторы и аутентификаторы, но тогда в нетворк модуль надо подключать базу или проперти и вытягивать токен из них
Retrofit поддерживает очень много всего. Но совсем не обязательно использовать абсолютно все фичи. Даже если какие-то из них ну очень нравятся. Local и remote data source срастаются в Repository. Поэтому получить token из базы, если он хранится там, и отдать прямо в метод api.fetchSms(token, ...) не составит труда.
@@illyaevseev312 токен подвязывается напрямую в апи сервисе аннотацией @Headers. Можно руками прокидывать в кастомный интерцептор. Тут как барин пожелает.
@@Ast991 По поводу @Headers. По-вашему я сказал что-то другое? По поводу интерцептора. Вы же помните, что мы говорим не о том, что можно написать интерцептор или нельзя? Мы говорим о том как поступить с точки зрения чистой архитектуры. Вы, конечно, можете меня переубедить, но пока я уверен, что кастомный интерцептор это remote data source и про базу данных вообще ничего не должен знать. Более того. Я уверен, что решать какой токен использовать и использовать-ли вообще должен в обсуждаемом случае все-таки repository.
А если у нас слишком сложная модель, которая например в себе содержает много данных и отношения к другим моделям, как с этим быть если дата сорс не может зависит от другого? Раньше у нас были разные репы для каждого из этих моделей, каждый раз тебе нужно хранить 1 модель тебе нужно зависит от кучу реп, и в некоторых местах эта логика повторялась, и пришлось добавить хелпер чтобы не копи пастить код, и с этим все у нас появилась проблема с консистентностью даннах. Мы решили что репа будет отвечать за главную модель, дата сорс также, но дата сорс зависит от других чтобы можно было хранить модели с которыми есть отношение, получилась у нас схема похожа на пирамиду, дата сорс ответственный за хранение главную модель, а за другие модели которые внутри ответственны другие дата сорсы, то есть дата сорс обращается к другим дата сорсам для хранения под-моделей, и потом только хранит свою модель. Другие дата сорсы также с начала обращаются к другим для хранения под-моделей и потом только свою. У нас так получилось решить проблему с кучей реп и кучей хелперов и других ответственных компонентов, также мы так гарантируем что данные хранятся в правильном порядке не важно какой у нас флоу, и все прозрачно так как нет никаких подводных камней.
@@MobileDeveloper У нас так было через юзкейсы/интеракторы. Но как показалась практика не очень подходящий вариант для сложных моделей и отношения между ними, мы решили сделать так, чтобы дата сорс был полностью ответственным за хранения всех этих данных, поэтому, в некоторых моментах когда есть many-to-many отношения, дата сорс может зависеть от другого. По старому подходу через юзкейсы у нас было грязнее намного. Пока я писал этот коммент, я понял что у каждого проекта своя специфика, и какие-то правила могут нарушаться чтобы не получить еще больше проблем, главное чтобы все было прозрачно и логично.
Я бы добавил, что должен быть source of truth в репозитории и логика по этой части должна быть там, остальная во ViewModel при использовании mvvm. Но это уже тема другого видео, похоже)
Хм... интересно. У меня сложился похожий подход. Овэрхэдить на проэкте - не есть хорошо. Но я бы сказал, что UseCase полезен почти всегда. А вот в Repository, при налиичии кейсов, я вообще особого смысла не вижу. Да это добавит некую декомпозицию но она логически неоправдана. Если мне нужно сходить на 3 ресурса, имея при этом токен - я сделаю 1 кейс, который обратится к локальному источнику за токеном, позже сходит по цепочке на нужные удаленные источники, а в случае протухшего токена - сходит на auth сервеер, обновит токен и повторит действа. Зачем нужны в таком случае репозитории, объеденяющие источники попарно?
как раз таки надо. красивое и понятное разбиение по слоям и наличие тестов и любое тестовое будет пройдено. если ревьюверам не понравится ваша структура пакетов и классов для пары экранов, то шансы сильно понижаются. то что вы красить кнопочки умеете, итак подразумевается.
Конечно, ведь цель тестового задания показать свои знания, а для проверяющего - оценить их. Любой профессионал скажет - что оверкодинг для тестового задания это отлично. Конечно же обе стороны должны понимать для чего это сделано.
Эм, ну так я блин в видео же и говорю, что для тестов ок. Только как правильно заметил Илья приложений без тестов 99% Будешь тесты писать тогда и сделаешь интерфейсы
То же самое по поводу кучи библиотек, возможно они вообще не нужны в вашем проекте и все задачи стандартным набором разработчика. И изучение этих библиотек отнимает время, а под капотом они используют то, что вами давно познано и отработано. Сегодня одна модная библиотека, а завтра на вашу голову придумают еще десять. Делюсь мыслью.
Хм, ну я просто всегда юзаю модули с интерфейсами и DI контейнерами. Тупо везде и всегда. И ни разу не пожалел. Накладные расходы минимальные, MV family штуки получаются как бы сами по себе только там где нужны. Минимализм это здорово, конечно, но как вы потом будете тестировать ваш код без контейнера зависимостей и интерфейсов? Стоит на проекте появиться , хотя бы, одному программеру кроме вас и уже появляется необходимость тестировать ваш код. А это тянет за собой требование к наличию той самой архитектуры... Поначалу все всегда просто, а потом "пара обновлений дизайна, пара новых фичей" и вы уже в говне по уши :) Поэтому я б даже калькулятор писал с DI контейнерами, интерфейсами, модулями и какой-то базовой архитектурой. Ну, я , правда, в геймдеве, мб в других отраслях специфика иная, но тут говна поесть на этом можно очень легко.
Как говорится на вкус и цвет ) я столько проектов знаю, где куча команд и при этом все руками тестируется, что искренне завидую, что вам так везет с автотестами ) Ну и сейчас можно прям классы мокировать) очень крутые либы стали
@@MobileDeveloper нет, пока не доросли еще, к сожалению, до автотестов. Тестирую модули все еще "руками" из вспомогательных классов, но , по крайней мере, это делается изолированно от остального проекта, а не падает на QA отдел, или коллег уже по факту. Но очень сильно руки чешутся протащить полноценные тесты в проект, ибо не все получается отловить так, да и время занимает. Не подскажете, что дельного можно почитать на тему автотестов и в целом внедрения их в C# проекты? Специфика - Unity/ gamedev.
Хорошее видео для общего понимания
Я бы не привязывался к количеству строк в классе для разбиения. Главный принцип здесь - SRP.
Если есть решение у команды использовать clean architecture, юз кейсы - будь добр использовать это во всех вью моделях и не тратить свои и ревьювера ментальные ресурсы на принятие решения.
Потом класс разрастается и что - надо рефакторить, тесты переписывать. Проще изначально сделать правильно
Один из лучших каналов для Android разработчика. Четко! Понятно! Без лишней воды! Алексею большое спасибо!
Лучший видос про архитектуры! Большое спасибо)
18:34 - SUS
А вообще спасибо за ролик, многим начинающим и не только будет полезно. Коротко и без избыточного углубления в тему 👌
Сразу видно, что видос прям о наболевшем) Еще бы это донести до тех аутсорс компаний, которые делают приложения и забывают про них, но надо обязательно упороться в "архитектуру", написать кучу лишнего и ненужного, чисто для того, чтобы показать мол видали, мы пишем "правильно"
самый часто нарушаемый принцип, это принцип KISS
Алексей правильные вещи говорит! Не усложняйте лишний раз.
Збазибо)
КИСС мой любимый принцип!!!
сначала ты ничего не усложняешь, не думаю о архитектуре, а потом через год говоришь бизнесу, что приложение не поддерживаемое и нужно переписывать)
@@aleksandrvolkov4310 Надо понять одно, автор просто забыл упомянуть, архитектура приложения это ни что-то незыблемое, а она так же должна развиваться с ростом проекта. Как пример, на другом канале рассказали про правило трех, когда у вас есть какой-нибудь метод в одном месте, вы можете смело его скопировать в другое, может слегка изменить. Но вот если это приходится делать в третий раз - это повод задуматься о выделении данного метода в отдельный класс и переиспользовании. Архитектура - это живая сущность, растет вместе с проектом и должна отвечать только тем требованиям, которые существуют на данном этапе.
По поводу выбора архитектуры я всегда вспоминаю одно наше приложение. В один прекрасный момент один наш постоянный клиент просит нас написать приложение-логинилку. Т.е. ты сканируешь QR код, отправляешь запрос на бэк и происходит какое-то действие. Например логин в системе или открытие электронного замка. Не вопрос. Я пишу его за пару дней и мы довольные расходимся. Проходит немного времени и выясняется, что нужно еще показывать статистику приходов на работу после логина. Запросто. А потом менеджеры очень запросили выводить статистику по процессам. И каждый раз звучало что-то из серии "вот это вот и все". Примерно первый год. Сейчас это CRM с SIP телефонией, чатами и целой кучей функционала. Изначально я закладывал архитектуру с избытком по отношению к функционалу. Как же сильно я в тот момент ошибался ;)
Интересная история 😀 но выглядит, что как раз в этой ситуации избыточность могла вас спасти )
@@MobileDeveloper Так я ведь тогда был абсолютно уверен, что перестраховался по полной. Хотя оказалось, что даже не начал страховаться.
От себя ещё накину, что любые правила, типа "если класс занимает больше N строк, то его нужно разбивать" конечно стоит держать в голове, но действовать все равно по ситуации. Если ваш класс хорошо согласован, не делает ничего лишнего, то пусть он занимает хоть 800 строк, вполне может быть так, что от разбиения код станет только запутаннее.
Ну в целом, да, но мы прям в линтере прописали эти правила и пока довольны )
800 строк это с учетом пустых строк, скобок закрытия и тд? А то бывает и презентер на 5к строк
Делал сложный компонент на JavaScript. Вот там 1000 строк было примерно.
Поддерживаю мысль что нужно делать только то что нужно, а что не нужно не делать)
Но с примером 19:08 когда отдельные модули делать не совсем согласен, в большинстве случаев над модулями начинают думать не когда команды параллельные есть, а когда твой монолитный модуль собирается минуту+ и это всех начинает напрягать. Главная их фича в том что и инкрементальный и клин билды намного предсказуемее работают, из-за чего проект можно скейлить и параллелить (А проблемы со временем сборки начинаются очень быстро, даже каких-нибудь 100к строк кода с каптом уже достаточно чтобы начать их ощущать). Так что это скорее про грэдл и котлин, и то как они устроены, а не про команду.
И даже более того, если "эта параллельная фича тима" будет просто жить в отдельном модуле без правильного контракта, то она зааффектит сборку гораздо сильнее чем если бы они писали всё в том же монолите, потому что перед монолитом теперь надо их модуль целиком собрать. Я бы тут сказал скорее "не лезте создавать модули если не понимаете к каким последствиям это приведёт, лучше монолит чем плохая модуляризация".
Как правило если у вас этот модуль уже собирается по 30 минут, то фича команды прям уже за углом )
У меня раньше был древнеримский ноутбук (6 ОЗУ), который проект на 2 экрана собирал 40 минут)))
@@maxhuman5898 А если очень хочется пощупать, и есть свободное время?
Спасибо дядь, норм раскидал.
Замечал у андроиндщиков в коде прикол с интерфейсами которые имплементятся 1й реализацией.
Спасииииибо! Мне за 5 лет уже начало казаться что я единственный человек который это понимает😢
Очень полезное видео, просто бальзам на душу! )
Отличное видео, даже для немного опытных!
Когда включился свет на заднем фоне - немного испугался, потом увидел девушку - стало полегче
Лайк! Но про 600 строк хз, как по мне это слишком много для андроид проекта. Уже после 300-400 возникает чувство что что-то не так и SOLID где то умирает в сторонке)
как же божественно запилил!
Делай как удобно, кажется это основной посыл видоса, мне например нравится закрывать классы интерфейсами (не все подряд очевидно) но если закрывать условную репу интерфейсом, так проще ориентироваться что есть внутри нее, просто почитал контракт с репой и погнал ее использовать (про многомодульность и тестирование тут не говорю)
Скорее посыл видео, что не надо плодить лишних сущностей без необходимости
Про интерактор, мне кажется стоит обратиться к первоисточнику th-cam.com/video/Nsjsiz2A9mg/w-d-xo.html. Потому что ваше объяснение ему не соответствует и только путает. Поправьте, если я что-то не знаю про Viper, но насколько мне известно, то там интерактор имеет абсолютно тоже значение что и в clean architecture. Интерактор - это объект реализующий сценарий использования.
абсолютно тоже самое и думал, интерактор это и есть юзкейс
Круто, согласен полностью и обеbми руками, ногами за каждое слово. Но только вот, еще бы на собесах от Junior не требовали бы clean architecture. Я конечно понимаю, что Junior должен хотя бы представлять, что это такое и на проекте не донимать вопросами дядей Seniors, что это такое и зачем. Но блин порой из-за дефицита кадров(Или жадности работодателей, все хотят за дешево спеца и сразу "херак-херак" продакшен) реально на позицию junior ищут midlle. И в итоге начинают делать pet проекты на 1-2 экрана с clean archeteture. Дабы показать, что они её знают, хотя она там нафиг не уперлась. Да и пониманию её, это ну ни разу не способствует:(
Я думал сейчас от джунов такое по дефолту уже требуется
1) Почему то про модули не сказал для ускорение сборки, на огромных проектах без разделения невозможно.
2) Про архитектуру в общем: если убрать тестирование, то она нужна для понимания проекта новым человеком.
3) Нужен ли обязательно домен слой(если нет какой-то бизнес логики, просто сходи в сеть и покажи результат), вопрос очень холиварный. В частности надо ли делать маппинг даат классов на каждом слое, иначе api response ответ, объявленный data слое будет виден в presentation, что не по клину))
4) Ещё бы добавить в видео пару слов о архитектуре, которая используется в гугловых примерах и кодлабах, многие берут оттуда, считая это эталоном.
Спасибо вам большое,Алексей!
Очень, очень годное видео! Спасибо)
Лучшее объяснение про архитектуру
Спасибо! Вы супер!
Спасибо!)
спасибо за видео , было очень познавательно
Ультра полезное видео, спасибо!
Я дед Евгений, внук установил мне язык программирования, я вхожу в Айти благодаря всем вам
Блин, очень классно, спасибо большое 🙏🙏🙏
что такое ентити зачем они нужны и чем отличаются от доменных моделей?
Интересное видео. У себя пришел к тому, что в 80% случаев в MVVM мне требовались только репозитории и в 20% - usecases к ним. Причем логика в usecase очень хорошо выделяется в процессе развития проекта, и изначально их плодить на каждый чих точно не стоит. Но не совсем согласен с запретом использования одного usecase из другого (горизонтальные зависимости) - если у них адекватное именование и взаимодействие внутри usecase логично и понятно, считаю, что не зачем городить еще один уровень абстракции создавая Interactor.
Спасибо за видео!
Спасибо за видео.Коммент в поддержку!
Спасибо!
Ну не только для команды или для маленьких проектов пишут архитектуру. Также для удобного написания тестов
Кто бы ещё писал эти тесты
@@MobileDeveloper На последних двух работах всегда пишем) В SberDevice, Epam.
@@MobileDeveloper ))))) на сто 46 % согласен
Функция в 50 строк? На мой взгляд, это до хера. 10-20 строк максимум, функция должна делать только одну логическую операцию если иначе, то ее необходимо разбивать на ряд малых фукций.
Я считаю если ты начинающий, "особенно начинающий" то архитектуру с юзкейсами и тд нужно пихать даже в калькулятор! Даже если ты не планируешь идти в команду, даже если это твое хобби от основной работы и ты не планируешь серьезно лезть в mobile development всегда везде следует делать архитектуру. Почему? Потому что должна вырабатываться привычка писать чистый читаемый код, это как в спортзале: если ты привык одевать пояс на присед с малым весом (допустим 30 - 50 кг), у тебя не будет проблем когда ты будешь приседать 90 - 120 ты первым делом автоматом будешь искать пояс потом только выполнять упражнение (безопасность превыше всего!). Еще пример: гораздо проще накидать юзкейсов и потом по ним продвигаться, чем сидеть и думать что тут должно быть или что тут еще можно добавить... я раньше не понимал подход database first типа "что за бред" 🤔, сейчас же наоборот, к UI перехожу в самую последнюю очередь когда все разложено "по полочкам" по пакетам по юзкейсам.
Разочарую, но database first тоже неверный подход. Верный это DDD, то есть сначала domain. th-cam.com/video/JOy_SNK3qj4/w-d-xo.html
9:54 а как же тестирование наших датасорсов, подмена реализации. может быть, на одном скрине нам нужно сохранять данные A , а на другом мы хотим сохранять данные B . Вы предлагаете скопипастить DataSource для сохранения A , чтобы создать DataSource для хранения B ? тогда нарушается DRY . или нам нужно перед сохранением данных B удалять данные A , тогда это можно решить паттерном декоратор))
Я говорю про тёплое, а вы про мягкое
Если нужно подменить это вопрос интерфейса, а не количества датасорсов.
Про интерфейс там дальше будет
Алексей, привет! А что-нибудь про микросервисы ты собираешься рассказывать? Был опыт?
чел ты хорош
Можете расказать что такое N-Tier architecture
Clean architecture
Onion architecture
Hexagonal Architecture
Layered architecture
Ports & Adapters architecture
Vertical Slices architecture
Event-Driven architecture
SOA architecture
Monolith architecture
Microservices architecture
Tdd, bdd, ddd, edd, stdd, atdd
Extreme pprogramming
command query responsibility segregation CQRS?
Хорошее видео, но если настолько упрощать архитектуру для проекта, который разрабатываешь один, то могут случиться исходники телеграма
Happy birthday, God blessing you.
Thank you very much ☺️
Благодарю за видео. Единственное не понял почему плохо, чтобы юз кейс использовал другой юз кейс. Например я в приложении работаю на одном экране со списком сущностей1, а на втором экране со списком сущностей2. Сущность1 хранит в себе список сущностей2. Сущность2 хранить в себе список сущностей3. Если использовать в юз кейс только репозитории, то возникает дублирование кода при сборке сущности2.
Горизонтальные зависимости плохи тем, что сегодня мы в UseCase1 добавляем зависимость от UseCase2 и у нас все вроде ок, а завтра оказывается что нам в UseCase2 нужна зависимость от UseCase1, и вот мы уже не можем пользоваться inject конструкторами даггера, потому что появляется циклическая зависимость (т.к. мы не хотим иметь несколько инстансов одного и того же юзкейса).
В вашем случае если сборка сущности2 слишком сложная, то можно ее вынести в какой-нибудь отдельный делегат, и его инжектить в каждый юзкейс
Видео здравого смысла!
Приветствую! Для меня как для недоджуна видео было максимально бесполезно. Надеюсь что я действительно всё пойму на реальном проекте :D
Привет, как тебе идея позвать на видео или стрим кого-нибудь из команды Language Design, и поговорить с ним о будущих дизайн фичах котлина, чем они сейчас занимаются, над чем больше всего работают и тд. Я думаю это будет оочень интересно
разбиение функций и классов должно быть конечно не по длине в строках, ибо длина в строках сильно зависит от особенностей конкретного языка и используемых конструкций, а в зависимости от цикломатической сложности и вообще здравого смысла. Т.к. функция или класс должны выполнять какое-то одно действие или быть расчитаны на одного актора, то это логически не позволяет классу или функции быть слишком большими, ибо они тогда начинают делать еще доп действия, которые они делать не должны
14:04 а что если есть бизнес логика отображать моментально на юай обновление Вьюхи после действия юзера , результат выполнения которого требует времени (запрос в сетку) , то здесь как по мне идеально подойдёт вложенный интерактор в другой интерактор, отвечающий за запрос в реальную сетку.
Господи как сложно все )
8:30 жертвуем увеличением количества кода. на клине приходится писать в разы больше и код под задачу будет размазан по нескольким файлам, а не по одному
В сервисе используется postgres, redis, clichouse, rabbitMQ. Сколько должно быть dataSources? Не выдумка, реальный сервис - часть большого проекта.
Скажите, пожалуйста, по поводу тестового задания для джуна. Если задание стандартное вроде 2х экранов список + детали, то делать всё по clean(слои, интерфейсы, мапперы) - это в плюс идет или в минус?
Меня бомбит от джунов и мидлов, которые MVP на MVVM натягивают и Clean архитектурой все это погоняют, но при этом не знают фундаментальных вещей по типу чем List от Set отличается.
А еще часто задаю очень простой вопрос на собесе: зачем нужна архитектура. И многих людей это ствит в тупик. И там идут ответы "Ну так надо" или "Все так делают"
Interactor и UseCase это разные названия одной сущности. Это одинаковые вещи, по-сути
Добрый день, когда ожидать видео про написание клиентской части playzone?
Топ контент: 🔥
Я думаю потому и используются несколько разных по ответственности data source в одном репозитории изза того, что domain слоя нет
13:05
Репозиторий по канонам должен иметь только один датасорс. А вот уже интерактор может в несколько репозиториев ходить
Спасибо за интересное видео. Но я не совсем понимаю почему горизонтальные зависимости плохи по вашему мнению? На мой взгяд когда для вычисления чего-то в юзкейсе нам нужен результат другого юзкейса - использовать его можно и нужно. Или вы считаете что лучше поставлять результаты других юзкейсов параметрами? Хотелось бы поимер ситуации когда вложенность юзкейсов вредит, а не помогает.
Пол слова знающего человека могут стоить многих дней поисков.
Немного не понятно в мобильной разработке. Нашёл круг A Comparison of Popular Flutter App Architectures (ui, web, db, external, interfaces, devices) внутри (controllers, gateways, presenters) внутри (use cases, entity) чем это связано с application layer (presentation, business logic, data access) и MVC, MVP, MVVM? В вебе всё делится на front end например angular(module->component->service->rest api) и back end например nest js (http request->controller->dto->service->dto->repository->entity->db) если не брать (Firebase как альтернативу) , а в мобилах всё вместе нету разделения на front и back? Ну хотя смотря какой вид рендеринга CSR(spa), SSR, SSG, LSR, RSC
О нашёл ios, swift clean arhitecture with MVVM
Ui (view) , View model - presentation layer (MVVM)
UseCase, interactor, entity - domain layer (business logic)
Repository, data source, api/storage service - data layer (data repositories)
Вот прям красавец, а то напилят калькулятор с 100500 усеркейсов)). Спасибо за видосик
ТОП ! Видео ТОП !
Спасибо )
Не согласен в деталях, да архитектура должна соответствовать масштабу проекта, но она всё равно должна быть, можно не использовать интеракторы/юзкейсы, но разбиение на модули и следование гайдам очень важно, тк во первых читаемость, расширяемость хорошая, и разделение ответственности автоматически, (+ интерфейсы лучше применять, и di и тестирование проще с ними) во вторых - в будущем на проекте будут работать другие люди, и они быстрее вьедут и не будет вопросов "че тут за говнокод". Плюс польза для самого себя - ты сразу заводишь привычку писать всё нормально, в итоге нет каши в голове типа "а надо тут или нет" - просто делай сразу нормально, и переделывать потом не надо будет, переделки множат говнокод и разнообразие в проекте, а хорошая архитектура - это минимум разнообразия в подходах. В больших проектах часто такое вижу, что модули сильно отличаются по реализации, надо пытаться минимизировать эту разницу
Помниться написал на PHP форум , с модерацией и т.д , там не то что клин архитектуры не было , там даже ООП не использовалось . Ни одного класса . Долго не мог понять зачем вообще эти классы нужны .
Интересует как в случае клин архитектуры передавать токен в ретрофит. У последнего есть хорошая вещь для этого - интерцепторы и аутентификаторы, но тогда в нетворк модуль надо подключать базу или проперти и вытягивать токен из них
При чем тут клин к ретрофиту? Ретрофит должен разруливать, dagger, koin и т.д.
Retrofit поддерживает очень много всего. Но совсем не обязательно использовать абсолютно все фичи. Даже если какие-то из них ну очень нравятся. Local и remote data source срастаются в Repository. Поэтому получить token из базы, если он хранится там, и отдать прямо в метод api.fetchSms(token, ...) не составит труда.
@@illyaevseev312 токен подвязывается напрямую в апи сервисе аннотацией @Headers. Можно руками прокидывать в кастомный интерцептор. Тут как барин пожелает.
@@Ast991 По поводу @Headers. По-вашему я сказал что-то другое? По поводу интерцептора. Вы же помните, что мы говорим не о том, что можно написать интерцептор или нельзя? Мы говорим о том как поступить с точки зрения чистой архитектуры. Вы, конечно, можете меня переубедить, но пока я уверен, что кастомный интерцептор это remote data source и про базу данных вообще ничего не должен знать. Более того. Я уверен, что решать какой токен использовать и использовать-ли вообще должен в обсуждаемом случае все-таки repository.
@@illyaevseev312 при чем тут токен к архитектуре вообще? Не смешите мои носочки
Сейчас пишу большое приложение в соло (похоже компании денег жаль) надеюсь, что если потом кому-то прийдётся разбираться с моим кодом он поймёт хД
А если у нас слишком сложная модель, которая например в себе содержает много данных и отношения к другим моделям, как с этим быть если дата сорс не может зависит от другого? Раньше у нас были разные репы для каждого из этих моделей, каждый раз тебе нужно хранить 1 модель тебе нужно зависит от кучу реп, и в некоторых местах эта логика повторялась, и пришлось добавить хелпер чтобы не копи пастить код, и с этим все у нас появилась проблема с консистентностью даннах. Мы решили что репа будет отвечать за главную модель, дата сорс также, но дата сорс зависит от других чтобы можно было хранить модели с которыми есть отношение, получилась у нас схема похожа на пирамиду, дата сорс ответственный за хранение главную модель, а за другие модели которые внутри ответственны другие дата сорсы, то есть дата сорс обращается к другим дата сорсам для хранения под-моделей, и потом только хранит свою модель. Другие дата сорсы также с начала обращаются к другим для хранения под-моделей и потом только свою. У нас так получилось решить проблему с кучей реп и кучей хелперов и других ответственных компонентов, также мы так гарантируем что данные хранятся в правильном порядке не важно какой у нас флоу, и все прозрачно так как нет никаких подводных камней.
Ничего не понял, но выглядит так как будто вам помогут юзкецсы )
@@MobileDeveloper У нас так было через юзкейсы/интеракторы. Но как показалась практика не очень подходящий вариант для сложных моделей и отношения между ними, мы решили сделать так, чтобы дата сорс был полностью ответственным за хранения всех этих данных, поэтому, в некоторых моментах когда есть many-to-many отношения, дата сорс может зависеть от другого. По старому подходу через юзкейсы у нас было грязнее намного. Пока я писал этот коммент, я понял что у каждого проекта своя специфика, и какие-то правила могут нарушаться чтобы не получить еще больше проблем, главное чтобы все было прозрачно и логично.
@@MobileDeveloper Спасибо за ролик) Шикарный)
Какие 600 строк-то? Замучаешься файл мотать. Дядя Боб говорил про 50 в среднем, но не больше 100.
не поняла сравнение с бритвой окама))
Я бы добавил, что должен быть source of truth в репозитории и логика по этой части должна быть там, остальная во ViewModel при использовании mvvm. Но это уже тема другого видео, похоже)
На эту тему можно бесконечно говорить )
Хм... интересно. У меня сложился похожий подход. Овэрхэдить на проэкте - не есть хорошо. Но я бы сказал, что UseCase полезен почти всегда. А вот в Repository, при налиичии кейсов, я вообще особого смысла не вижу. Да это добавит некую декомпозицию но она логически неоправдана. Если мне нужно сходить на 3 ресурса, имея при этом токен - я сделаю 1 кейс, который обратится к локальному источнику за токеном, позже сходит по цепочке на нужные удаленные источники, а в случае протухшего токена - сходит на auth сервеер, обновит токен и повторит действа. Зачем нужны в таком случае репозитории, объеденяющие источники попарно?
Чтобы иметь право решать что нужно, а что не нужно, надо быть мидлом-синьером) Об этом никто не говорит только))
В своём прокаты ты сам себе синьор
Да и на галерах часто ты сам себе синьор
Нужно ли делать датасоурс, репоситорий для тестовых заданий, если даже 2-3 екрана и простая логика?
Нет, если только это не цель задания
как раз таки надо. красивое и понятное разбиение по слоям и наличие тестов и любое тестовое будет пройдено. если ревьюверам не понравится ваша структура пакетов и классов для пары экранов, то шансы сильно понижаются. то что вы красить кнопочки умеете, итак подразумевается.
Конечно, ведь цель тестового задания показать свои знания, а для проверяющего - оценить их. Любой профессионал скажет - что оверкодинг для тестового задания это отлично. Конечно же обе стороны должны понимать для чего это сделано.
Единственная архитектура на андроид это чистая архитектура)) Mv* это же ведь шаблоны проектирования
Оскара ему Оскара!!!
Какие вопросы задают на собесе про cleanархитектура
В основном самые простые, а-ля что такое домен, дата слой. Зачем вообще все это нужно)
Чувак, когда говоришь умные мысли, у тя лютые мышечные тики на лице.
А ты думаешь я не в курсе?
просто треп
Блин, как же все сложно в этих мобильных приложениях…
Капец вообще 😀
Освети многомодульность пж)
Освящаю! Да будет многомодульность ободрена, положена и в градл запущена!
@@MobileDeveloper 🤣🤣🤣
Лучше понял что такое "код ради кода"
интерфейсы нужны для тестирования. а это важно при любой арихитектуре
Только проектов, где тесты не пишут, вагон и маленькая тележка. Если их писать никто даже не собирается, то в чем смысл их делать?
Эм, ну так я блин в видео же и говорю, что для тестов ок. Только как правильно заметил Илья приложений без тестов 99%
Будешь тесты писать тогда и сделаешь интерфейсы
То же самое по поводу кучи библиотек, возможно они вообще не нужны в вашем проекте и все задачи стандартным набором разработчика. И изучение этих библиотек отнимает время, а под капотом они используют то, что вами давно познано и отработано. Сегодня одна модная библиотека, а завтра на вашу голову придумают еще десять. Делюсь мыслью.
Хм, ну я просто всегда юзаю модули с интерфейсами и DI контейнерами. Тупо везде и всегда. И ни разу не пожалел. Накладные расходы минимальные, MV family штуки получаются как бы сами по себе только там где нужны. Минимализм это здорово, конечно, но как вы потом будете тестировать ваш код без контейнера зависимостей и интерфейсов? Стоит на проекте появиться , хотя бы, одному программеру кроме вас и уже появляется необходимость тестировать ваш код. А это тянет за собой требование к наличию той самой архитектуры... Поначалу все всегда просто, а потом "пара обновлений дизайна, пара новых фичей" и вы уже в говне по уши :)
Поэтому я б даже калькулятор писал с DI контейнерами, интерфейсами, модулями и какой-то базовой архитектурой.
Ну, я , правда, в геймдеве, мб в других отраслях специфика иная, но тут говна поесть на этом можно очень легко.
Как говорится на вкус и цвет ) я столько проектов знаю, где куча команд и при этом все руками тестируется, что искренне завидую, что вам так везет с автотестами )
Ну и сейчас можно прям классы мокировать) очень крутые либы стали
@@MobileDeveloper нет, пока не доросли еще, к сожалению, до автотестов. Тестирую модули все еще "руками" из вспомогательных классов, но , по крайней мере, это делается изолированно от остального проекта, а не падает на QA отдел, или коллег уже по факту.
Но очень сильно руки чешутся протащить полноценные тесты в проект, ибо не все получается отловить так, да и время занимает.
Не подскажете, что дельного можно почитать на тему автотестов и в целом внедрения их в C# проекты? Специфика - Unity/ gamedev.
В C# не подскажу ) у меня все таки мобильная разработка, но думаю та же пирамида тестирования она относится к любому виду программных продуктов
@@MobileDeveloper угу, погуглю, спасибо!
Сборник вредных советов. Главное голос поувереннее.
Пока никто не видит мои модели сами себя сохраняют в базу на .save() и умеют преобразовываться в другие модели dogRealm.threadSafeModel() ...