Что такое code smells и его устранение

  Рет қаралды 15,784

Sergey Nemchinskiy

Sergey Nemchinskiy

Күн бұрын

Пікірлер: 104
@nickolaydrozdov
@nickolaydrozdov 7 ай бұрын
Сижу вырезаю тонны древних комментов из кода и тут такое видео😂 Спасибо ❤
@sergeypekar1058
@sergeypekar1058 7 ай бұрын
Надо стрим запилить. Открыть какой-нибудь проект и на прямом примере показать где плохо, а где хорошо)
@TheRodanid
@TheRodanid 7 ай бұрын
Интересно и познавательно. Спасибо, Сергей и команда Foxminded!
@LeonidYakovlev85
@LeonidYakovlev85 7 ай бұрын
Сергей и весь коллектив канала, традиционное спасибо за выпуск, как всегда здорово - интересно и содержательно 🙏
@borisisavnin9983
@borisisavnin9983 7 ай бұрын
Очень понравилось про закоментированный код, слушал и удалял) Отвлекся на минуточку пост тиснуть и сейчас же продолжу. Спасибо, Сергей и твоя команда!
@feddos4227
@feddos4227 7 ай бұрын
13:01 Тут вообще мимо. Делать переменные что бы получить результат функции и передать дальше - абсолютно нормально, и как раз таки по рукам нужно бить когда пишут вот так: send_to_server(get_sensor_value()). Во-первых, используя переменную, удобнее читать код, потому что если это будет функция, параметр которой вызов другой функции, у которой параметр вызов ещё одной функции- это тихий ужас. Во-вторых, возможно результат нужно будет потом где-то использовать, и не нужно будет переносить туда сюда вызов функции. Ну и самое главное: Дебаг. Дебажить код, где результат каждого вызова находится в своей переменной - намного проще, ибо как узнать результат функции, значение которой передаётся сразу в другую - непонятно. Разве что в некоторых дебаггерах можно прямо в дебаггере вызвать функцию, но это такое себе, ибо не факт что результат будет таким же
@nicolas267s
@nicolas267s 7 ай бұрын
Ага, особенно когда таких вызовов много. Читабельность ниже плинтуса. return getSome(getSomethingElse().getAnotherSome(new HereWeGoAgain(name, code)), getThisOneToo());
@vladbarkovsky3939
@vladbarkovsky3939 7 ай бұрын
очень в тему. спасибо, сергей!
@mmogamespace
@mmogamespace 7 ай бұрын
Получается вчера на стриме был "индус" со своими case'ми :)
@vladimirgaydamakin7155
@vladimirgaydamakin7155 7 ай бұрын
хорошее видео
@Mr43046721
@Mr43046721 7 ай бұрын
Спасибо за видео Сергей, классная кофта)
@vlera4198
@vlera4198 7 ай бұрын
помню я все таки писал комменты в коде. алгоритм был сложноватый и гдето с 3-й строчки у меня самого дымок из ушей шел и я просто даже для себя написал что вот тут я удаляю то-то для тогото и в другом месте тоже чтото написал. Синьоры которые обычно любили клевать на ревью на эти комменты не делали замечания, ну там реально сложно было понять просто читая код, ну и в итоге работал он быстро
@semyontikhonenko7937
@semyontikhonenko7937 7 ай бұрын
Во всех современных языках давно есть передача параметров по названию
@АндрейЧеремисин-щ7к
@АндрейЧеремисин-щ7к Ай бұрын
вне зависимости от того, какой флаг все время мелькает на видео, хочу сказать что автор снял отличное видео, respect +
@ЕрвандАгаджанян-в3к
@ЕрвандАгаджанян-в3к 7 ай бұрын
Интересен тренинг по рефакторингу))
@rudolfsikorsky7900
@rudolfsikorsky7900 7 ай бұрын
Бывает код, покрытый тестами, а у меня - код, порытый туду-шками :)
@Удалить-ю3у
@Удалить-ю3у 7 ай бұрын
"Ненужные переменные", которые сразу после получения передаются, делают для целей отладки, когда нужно понять, что именно возвращает метод. В релизном коде оптимизатор, скорее всего уберет эту переменную.
@oshastitko
@oshastitko 6 ай бұрын
да причём тут релиз. Любой "запашок кода" - это для программиста, компилятору вообще пофиг по большому счёту, как код написан, если он выполняет тоже самое. Ненужные переменные усложняют чтение и понимание, по ним непонятно, участвуют они вообще в процессе, влияют на что-то или нет
@vladbarkovsky3939
@vladbarkovsky3939 7 ай бұрын
меня кстати реально бесит закомментаренный код. типа, там ещё сверху написано "не трогать, оно будет надо тогда-то" причём, оно надо тогда-то уже больше года. я всегда в PR делаю пунктик в конце: "а ещё я удалил из такого-то файла 150 строк кода, который делал ничего". и всёравно мне кидают в PR комментарии "зачем ты убрал - оно будет надо".
@jakksoft
@jakksoft 7 ай бұрын
Не хватает усидчивости самому читать книгу по рефакторингу, сделайте пожалуйста видеооо, все 10 часов 3 раза пересмотрю)
@Karpick_ds
@Karpick_ds 7 ай бұрын
Эх, Сергея Немчинского больше не зовут «всё ещё Сергей Немчинский» (( Ушла эпоха
@mykola-rohoza
@mykola-rohoza 7 ай бұрын
За тренинг по рефакторингу двумя руками
@WSSAWER
@WSSAWER Ай бұрын
Длинные методы. Любой длинный маталгоритм даже в ненагруженной среде будет больше страницы. Так же бывает с теми вещами, что обрабатывают большие данные из-за требований к скорости. Свитч-кейс - один из самых удобных инструментов. Во многих языках это так же хороший способ типизации и проверки условий(например, в шарпе). Гораздо лучше читаемый. Про проперти тут уже говорили. Для загрузки файла конфигурации - очень частое явление. Но бывает и, например, указание параметров точки. Это уже несколько разнотипных параметров(координата, вращение, параметрытекстуры, направление). Создавать отдельный не функциональный класс только для передачи данных, выдавать его в общем контексте(namespace) для передачи данных? Это же те самые сгустки данных... Локальные переменные полезны для отладки. Если часто нужно - можно и так оставить. Многое из этого - вообще мелочи) С улучшением языков и IDE книги устаревают, и именитые разрабы за ними часто не успевают. А в целом - отлично)
@torrvic1156
@torrvic1156 7 ай бұрын
Большое спасибо за то, что делитесь знаниями, Сергей! Но вот про свич всё-таки некоторые опытные программисты говорят, что он не так уж и плох. Конечно же хотелось бы ваш рассказ про рефакторинг :) Читать влом))
@oshastitko
@oshastitko 6 ай бұрын
"свитч не так уж и плох" может быть только для совсем примитивных вещей, когда, например, записать разные строки в зависимости от значения в какой-нибудь условный лог (и не более) проще, нежели городить и внедрять ещё одну сущность и только в том месте, которая гарантированно будет всегда простой как двери и не требующей тестирования. Тогда, может быть, допускается этот свитч (и то, я не сторонник его, потому как иногда даже совсем простые вещи начинают разрастаться, требуют изменения в старый код и провоцируют регрессивное тестирование)
@dmitriy9232
@dmitriy9232 6 ай бұрын
Даешь тренинг по рефакторингу! ))
@ПавелМароков-э8л
@ПавелМароков-э8л 7 ай бұрын
я программист-любитель. но когда мне нужны были просто координаты - я создал класс с переменными X, Y и сеттерами/геттерами. мне это показалось очевидным! сам додумался! ))
@simpleman6617
@simpleman6617 7 ай бұрын
К многим из приведенным здесь советам я допер сам методом проб и ошибок набивая себе шишки-это издеьржки того что я самоучка. Тише едешь дальше будешь - если не торопясь дапшь осмысленные имена переменным если не полениться и вставить коментарий - потом будет проще. Еще много зависит от языка - помню на бейсике была такая каша...
@miminorka
@miminorka 7 ай бұрын
вообще очень категорический совет и уж точно неприменимый ко всем ситуациям, повторение (копирование) кода вполне нормально к тем местам, где мы уверенны что логика будет другой, в тех же местах где нам надо чтобы логика была той же, но обьекты другими, надо переделывать под дженерики а не копировать
@oshastitko
@oshastitko 6 ай бұрын
если у вас есть похожая, но не точно такая же логика, то это повод вычленить из неё идентичные участки, создать базовый (скорее всего, абстрактный) класс, реализующей эти участки (хотя в последней версии шарпа можно и в интерфейсах писать логику :) ) и в классах-наследниках уже реализовать различия, реализовав соответствующие абстрактные методы, а не городить 2 похожих кода в разных местах
@kasparzubarev
@kasparzubarev 7 ай бұрын
Если вы пишете на С то полезным будет посмотреть на то как организованы "конструкторы" структур в исходниках ядра Linux. В некоторых драйверах применяются принципы аналогичные принципам используемым в ООП, особенно в драйверах работающих с видеоподсистемой V4L2. Можно много занимательного почерпнуть
@ВячеславСергеевич-у1н
@ВячеславСергеевич-у1н 7 ай бұрын
Я добавил бы следующее к code smells: 1) это создание объектов, классы которых реализуют один и тот же интерфейс, через new. Лучше использовать аннотации + рефлексия и создавать объекты в ObjectFactory 2) Использовать pojo классы, сформированные на основе json, вместо этого использовать JsonObject или String + jsonPath
@AlexeySukharenko
@AlexeySukharenko 7 ай бұрын
Я бы еще к плохому коду отнес лишком длинные классы
@randomisgood2619
@randomisgood2619 7 ай бұрын
Ура, новое видео!
@mrbshorts6002
@mrbshorts6002 7 ай бұрын
Не могли вы снять видео что должен знать джуниор с++
@romanalexandrov2880
@romanalexandrov2880 7 ай бұрын
Раньше, когда я что-то переделывал в коде, то заодно сразу рефакторил и закомменченые части - и даже так они мне ни разу не пригодились =D С тех пор, как это заметил, удаляю их без тени сомнения
@darkart6487
@darkart6487 7 ай бұрын
Да я так хотел зарефакторить крафт и готовку. В общем всё вроде нормально объединил, но суть до дела полается нужны другие переменные чтобы показать отличия. Код становится непонятной лапшой. Вывод лучше пусть код повторяется, чем он становится непонятным с первого взгляда
@ДенисДенис-в3э
@ДенисДенис-в3э 7 ай бұрын
Спасибо большое за Ваши видео. Прокомментируйте пожалуйста Apple Vision Pro, какие перспективы Вы видите, какой язык понадобится для разработки приложений под Vision Pro. Спасибо !
@SergeyNemchinskiy
@SergeyNemchinskiy 7 ай бұрын
перспективно. Свифт
@СергейМитяев-п1н
@СергейМитяев-п1н 7 ай бұрын
"одноразовые переменные" использую при отладке, если получаемый объект зависит от времени, или сложно конструировать.
@nicolas267s
@nicolas267s 7 ай бұрын
9:05 Я как-то раз дебажил код, в котором один метод отвечал за сразу за чтение, создание, обновление и удаление (!!!) сущностей, в зависимости от набора параметров. Вишенкой на торте было то, что метод, к тому же, вызывался из десятков разных мест. И нет, там не было просто параметра типа action, туда передавалось с десяток разных параметров и всё это иффалось по - "пойди разбери какой" логике. Сам баг заключался в том, что при открытии определённой страницы из базы пропадали данные(кто бы мог подумать...). Естественно я не стал продолжать эту вакханалию, не стал просто подбирать параметры, а разделил все эти функции по своим методам. Тут и список параметров резко сократился. Надеюсь у автора этого кода уши горели, пока я этот клубок распутывал.
@PerfectHolyPervert
@PerfectHolyPervert 7 ай бұрын
Спасибо за рекомендацию по поводу книги по рефакторингу.
@diatm1506
@diatm1506 7 ай бұрын
Сергей что Вы думаете о книге Khalila Stemmlera The Software Design & Architecture Handbook?
@D1LLERH
@D1LLERH 7 ай бұрын
А где Сергей Немчинский? Он вернётся?
@__ali__97
@__ali__97 7 ай бұрын
Та самая тонкая грань, между дублированием кода и принципа SRP, как понимать когда нужно реюзнуть уже имеющийся код, а когда нужно написать похожий код, но использующийся в другом месте с похожей, но не точно такой же логикой.
@oshastitko
@oshastitko 6 ай бұрын
если у вас есть похожая, но не точно такая же логика, то это повод вычленить из неё идентичные участки, создать базовый (скорее всего, абстрактный) класс, реализующей эти участки (хотя в последней версии шарпа можно и в интерфейсах писать логику :) ) и в классах-наследниках уже реализовать различия, реализовав соответствующие абстрактные методы, а не городить 2 похожих кода в разных местах
@pash0k13
@pash0k13 7 ай бұрын
"12:44 - ненужные примитивные переменные" - вот не согласен. есть еще простота и читаемость кода. если будет метод, и в этом при вызове метода для передачи значений вызываются еще методы, несколько, - то можно глазки сломать. пример foo(foo1(value1, value2), foo2(value1), foo3(value1, value2, value3)); 👀. уф... если спуститься на уровень ниже - то все равно создается область в памяти, которая содержит результат выполнения метода и затем передается в метод. если создать переменную для сета в метод - то эта переменная будет указывать на результат выполнения метода и затем этот результат будет передан методу который нуждается в этой переменной. в таком случае читаемость кода возрастает в разы. в итоге: не всегда нужно избавляться от переменных которые потом используются в одном месте. как вариант, когда нужно избавиться - если в методе есть переменная, а потом она же возвращается значение из метода - то да, тут хорошо срезу результату делать ретурн.
@SergeyNemchinskiy
@SergeyNemchinskiy 7 ай бұрын
я и не говорил - всегда
@pash0k13
@pash0k13 7 ай бұрын
@@SergeyNemchinskiy да, но в контексте будто бы подразумевается 'всегда'. ще раз дякую за мувік!
@Petrovi_-tv5et
@Petrovi_-tv5et 7 ай бұрын
Здравствуйте , можете пожалуйста обьяснить на простых словах про DOM JS ? Спасибо
@MaximKacc
@MaximKacc 7 ай бұрын
Да уж, индусы нынче switch-case'ом пишут)
@Vlad-ok8wp
@Vlad-ok8wp 7 ай бұрын
Коли вкотре чую що метод повинен буту не більше строрінки, так і хочу показати це відіо своєму шефу. В мене на фірмі код в 1000 строк це норма, максімально здається десь біля 2000 . Колі я почінаю працювати с новим для мене методом, пару годин може знадобитись щоб зрозуміти як це працює.
@perekhrestdimon
@perekhrestdimon 7 ай бұрын
Вопрос: Если я учусь по видео и делаю по ним проекты, смотрю, что делает автор, и повторяю за ним, и так делаю сайты, это копипастинг? Стоит так делать, или лучше делать самому? Спасибо заранее!
@SergeyNemchinskiy
@SergeyNemchinskiy 7 ай бұрын
Это нормально для начала учебы, но уже пора начинать делать все самому
@azamjon40
@azamjon40 7 ай бұрын
Я удалаю тоже, даже не принимаю такой код )))
@zarazlik789
@zarazlik789 7 ай бұрын
Даешь тенинг
@РоманОболонский-ц8н
@РоманОболонский-ц8н 7 ай бұрын
На счет мертвого кода, который никто не юзает. Если не ошибаюсь, то компилятор детектит такие куски кода и выкидывает их
@Александр-о5о3й
@Александр-о5о3й 7 ай бұрын
Дело не в компиляторах, а в том что человеку не удобно.
@miminorka
@miminorka 7 ай бұрын
вобще с такими радикальными методами без рассмотрения других вариантов это конечно же экстремизм
@oshastitko
@oshastitko 6 ай бұрын
в чём радикализм?
@olegoleg135
@olegoleg135 7 ай бұрын
Про "закомментированный" код улыбнуло. Каждая нормальная IDE поддерживает сворачивание блоков кода любого размера, так что это точно не должно являтся проблемой. Также иногда бывает полезным оставлять такие блоки, чтобы в дальнейшем понимать, как возникла новая версия этого блока. Например, какой-то сложный алгоритм, который был изначально реализован в каком-то методе, потом этот метод был существенно переделан, но без старой версии этого метода трудно понять(если вобще возможно), почему именно так в последствии был реализован алгоритм в данном методе.
@oshastitko
@oshastitko 6 ай бұрын
Если новая версия без старой не читается - то, скорее всего, у вас не очень хорошо реализована новая версия. Это скорее повод для рефакторинга, а не повод оставления старого и, скорее всего, уже неработающего кода. Если понять всё равно тяжело - значит, у вас метод взял на себя слишком много, дробите его. Резюмируя: желание оставить старый код прежде всего говорит о проблемах в новом коде
@alekseyshibayev5243
@alekseyshibayev5243 7 ай бұрын
Сергей, давно вы современный код не видели, особенно сеньерский. Java превратили в паскаль. Кругом инжект очередного бла-бла-бла-Service, var и перегруженные цепочки функциональщины.
@SergeyNemchinskiy
@SergeyNemchinskiy 7 ай бұрын
да видел
@miminorka
@miminorka 7 ай бұрын
копирование кода оправдано 100 если заранее известно что он будет работать отлично от исходного, и в этом случае копировние оправдано, об этом нужно сказать
@shurko
@shurko 7 ай бұрын
Не надо тренинг.
@krivodeling7925
@krivodeling7925 2 ай бұрын
+
@СергейНасакаев-п1ь
@СергейНасакаев-п1ь 7 ай бұрын
Конечно, братан, всё нужно: " робить будем пока не помрём." Как говорил один "ИЗ": " куй железо, не отходя от кассы!".
@СергейНасакаев-п1ь
@СергейНасакаев-п1ь 7 ай бұрын
А ещё:" полян'ыца". Всё.
@VitalySem
@VitalySem 7 ай бұрын
Що за напівміри? Пахне, попахує, він смердить))
@Feelmeee-p6s
@Feelmeee-p6s 7 ай бұрын
Непонятно что за символ в левом верхнем углу переливается двумя цветами🤔🤔 404
@ЭлайтСолт
@ЭлайтСолт 7 ай бұрын
Все гораздо проще! Как сказал один великий программист: Если твой код работает корректно и выполняет свой функционал,значит - это хороший код. Все остальное второстепенно
@nicolas267s
@nicolas267s 7 ай бұрын
Типичная ошибка новичка. Любой код рано или поздно ломается, или его приходится дополнять. Если новому разработчику приходится в твоём коде неделями ковыряться, чтобы разобраться, то это плохой код.
@ЭлайтСолт
@ЭлайтСолт 7 ай бұрын
@@nicolas267s Это не мои слова, это слова программиста Маркуса Перссона.
@sergiisuprun
@sergiisuprun 7 ай бұрын
Читать книги, когда IDE все подсвечивает и подсказывает, вы серьезно?
@SergeyNemchinskiy
@SergeyNemchinskiy 7 ай бұрын
угу
@itlife8792
@itlife8792 7 ай бұрын
еще бывает оставляют, старый код закоменченным (прям огромными блоками), или вешают @Deprecated с ссылкой. на новый метод, но я сторонник удалять такое, хотя кто-то оставляет @Deprecated методы, чтобы понять, какой метод пришел на замену
@andreasstager1642
@andreasstager1642 7 ай бұрын
В большинстве нормальных компиляторов есть tree shaking, который отбрасывает неиспользуемый код. Как код, который никто никогда не вызывает, может приводить к ошибкам, для меня вообще загадка.
@sergeypekar1058
@sergeypekar1058 7 ай бұрын
Еще как может. У меня такое было не один раз когда я начинал использовать какой-то легаси класс (который, кстати, как легаси никто не пометил(, а потом, оказывалось, что он уже давно устарел и нужно было использовать другой. А все потому, что кто-то решил, что это хорошая идея - оставить старый код в проекте
@vanstrihaar
@vanstrihaar 7 ай бұрын
Лайт-вариант - новички могут посмотреть и решить "раз есть - значит норм", и делать похоже.
@nicolas267s
@nicolas267s 7 ай бұрын
Очень просто может, хоть на этапе компиляции, это проще исправить, хоть при запуске. Например, если зависимый код был изменён. Даже если его в рантайме никто не вызывает, он может загружаться при инициализации и кидать исключения.
@vanstrihaar
@vanstrihaar 7 ай бұрын
Я стараюсь избегать использование вызова метода в качестве параметра, только в простых случаях. А когда в одной строке вызовов методов 3 и больше - код может тяжело читаться. С другой стороны имя промежуточной переменной может помочь в понимании кода.
@sergeiseivach
@sergeiseivach 7 ай бұрын
Совершенно верно, и брейкпоинт поставить на промежуточную переменную - тоже удобно. Как говорит один известный IT-блоггер: любой дурак может написать код, понятный компьютеру. Хороший программист пишет код, понятный человеку
@oshastitko
@oshastitko 6 ай бұрын
скажем так, лично я не ставлю себе рамок и пишу и так, и эдак в зависимости от "интуитивной необходимости". И да, это единственный аспект в видео, с которым я в чём-то не согласен
@AlexesUA
@AlexesUA 7 ай бұрын
Мені точно сподобався би тренінг по рефакторінгу. Та й відео на ~20 годин зайшло би. 20 годин розслабляючого голоса Сергія.... Каєф... 😅
@Carrergt
@Carrergt 7 ай бұрын
Так буде цікавим. Можливо буде наступним після GRASP and GOF
@MsSmartFox
@MsSmartFox 7 ай бұрын
"тимчасові" змінні стануть в нагоді коли ти будеш дебажить код. Замість того щоб визивати метод який повертає значення у code evaluation вікні, ти просто стаєш на потрібний рядок дебагером та дивишся шо метод повернув, та що ти передаєш далі.
@SergeyNemchinskiy
@SergeyNemchinskiy 7 ай бұрын
Взагалі-то будь який дебагер дозволяє подивитись результат визову метода. А ще, краще намагайтесь юзать логуванне + юніт тести заміст дебагга
@PEREPELITSA_KIRILL
@PEREPELITSA_KIRILL 7 ай бұрын
Прекрасное видео ещё одна хорошая книга в копилку. Спасибо Сергей пойду читать. А на счёт тренинга да хотим и курс по java тоже а что нет)
@illia4228
@illia4228 7 ай бұрын
Тренинг по рефакторингу интересен!
@profile_pub190
@profile_pub190 7 ай бұрын
Ещё бы к запахам кода отнёс void метод get, который что-то изменяет, и метод set который возвращает какое-то измененное значение, и их комбинация когда пропускают промежуточные переменные и в аргументы метода get передают возвращаемое значение метода set 😂 и это не придумано, а описание случая из жизни
@SergeyNemchinskiy
@SergeyNemchinskiy 7 ай бұрын
да ну нахер :) остановите землю, я сойду
@profile_pub190
@profile_pub190 7 ай бұрын
@@SergeyNemchinskiy земля в безопасности - было переписано, ускорено и сейчас только история гита хранит упоминание об этом
@oshastitko
@oshastitko 6 ай бұрын
у вас уже прям какие-то извращения.... 😀
@profile_pub190
@profile_pub190 6 ай бұрын
@@oshastitko доводилось переделывать плохо пахнущий (и работающий) код. В одном случае был труд индийской студии и там транзакция в БД ждала ответа платежного сервиса :D
@andreasstager1642
@andreasstager1642 7 ай бұрын
Parameter object - костыль для языков, где нет named-параметров. Надо было бы сделать на этом акцент.
@HelloWorld-ln5cy
@HelloWorld-ln5cy 7 ай бұрын
Обьясни что такое named- параметры, а то не понятно о чем ты.
@andreasstager1642
@andreasstager1642 7 ай бұрын
@@HelloWorld-ln5cy Смотри например Dart.
@_dzen_tv_
@_dzen_tv_ 7 ай бұрын
@@HelloWorld-ln5cy function_name(position_param_0, position_param_1, named_param_0=default_value_0, named_param_1=default_value_1) вызов function_name(value_0, value_1, named_param_0=named_value_0, named_param_1=named_value_1) начиная с 3-го именованные параметры А так да в том же winapi функция + структура к ней на десяток параметров.
@HelloWorld-ln5cy
@HelloWorld-ln5cy 7 ай бұрын
@@_dzen_tv_ а понял, это не особо решает проблемы, да код немного читаем становится, в c# есть то что вы описали, но это не особо популярный подход, куда проще вместо кучи параметров передать один обьект или структуру и не морочить голову, особенно если эти данные постоянно используются вместе, по типу векторов, проще передать структуру чем три параметра по отдельности. Автор ролика именно о таком и говорит.
@_dzen_tv_
@_dzen_tv_ 7 ай бұрын
@@HelloWorld-ln5cy тут есть нюанс get_users(UserFilter(param0=0, param1=1, ...)) против get_users(param0=0, param1=1, ...) Другое дело что архитектурно get_users будет расположена на слое репозиториев, а UserFilter будет определён где-нибудь в файле filters.
Программист, ты должен писать плохой код
21:51
АЗАРТНИК 4 |СЕЗОН 2 Серия
31:45
Inter Production
Рет қаралды 1,1 МЛН
Новый уровень твоей сосиски
00:33
Кушать Хочу
Рет қаралды 4,8 МЛН
POV: Your kids ask to play the claw machine
00:20
Hungry FAM
Рет қаралды 22 МЛН
HTTP в 1С за 3 часа
3:23:54
IRONSKILLS - Курсы по 1С
Рет қаралды 445 М.
Swift Programming Tutorial for Beginners (Full Tutorial)
3:22:45
CodeWithChris
Рет қаралды 7 МЛН
Стивен Уильям Хокинг. Теория всего. Происхождение и судьба Вселенной.
3:28:26
Читает Олег Лобанов | ≡ Аудиокниги
Рет қаралды 1,5 МЛН
СУРДИН и СЕМИХАТОВ смотрят запуск STARSHIP,  ИЛОН МАСК  волнуется. Стрим.
2:51:55
Неземной подкаст Владимира Сурдина
Рет қаралды 959 М.
Исправляем очень плохой код | Clean Code
21:34
Sergey Nemchinskiy
Рет қаралды 16 М.