Сижу вырезаю тонны древних комментов из кода и тут такое видео😂 Спасибо ❤
@sergeypekar10587 ай бұрын
Надо стрим запилить. Открыть какой-нибудь проект и на прямом примере показать где плохо, а где хорошо)
@TheRodanid7 ай бұрын
Интересно и познавательно. Спасибо, Сергей и команда Foxminded!
@LeonidYakovlev857 ай бұрын
Сергей и весь коллектив канала, традиционное спасибо за выпуск, как всегда здорово - интересно и содержательно 🙏
@borisisavnin99837 ай бұрын
Очень понравилось про закоментированный код, слушал и удалял) Отвлекся на минуточку пост тиснуть и сейчас же продолжу. Спасибо, Сергей и твоя команда!
@feddos42277 ай бұрын
13:01 Тут вообще мимо. Делать переменные что бы получить результат функции и передать дальше - абсолютно нормально, и как раз таки по рукам нужно бить когда пишут вот так: send_to_server(get_sensor_value()). Во-первых, используя переменную, удобнее читать код, потому что если это будет функция, параметр которой вызов другой функции, у которой параметр вызов ещё одной функции- это тихий ужас. Во-вторых, возможно результат нужно будет потом где-то использовать, и не нужно будет переносить туда сюда вызов функции. Ну и самое главное: Дебаг. Дебажить код, где результат каждого вызова находится в своей переменной - намного проще, ибо как узнать результат функции, значение которой передаётся сразу в другую - непонятно. Разве что в некоторых дебаггерах можно прямо в дебаггере вызвать функцию, но это такое себе, ибо не факт что результат будет таким же
@nicolas267s7 ай бұрын
Ага, особенно когда таких вызовов много. Читабельность ниже плинтуса. return getSome(getSomethingElse().getAnotherSome(new HereWeGoAgain(name, code)), getThisOneToo());
@vladbarkovsky39397 ай бұрын
очень в тему. спасибо, сергей!
@mmogamespace7 ай бұрын
Получается вчера на стриме был "индус" со своими case'ми :)
@vladimirgaydamakin71557 ай бұрын
хорошее видео
@Mr430467217 ай бұрын
Спасибо за видео Сергей, классная кофта)
@vlera41987 ай бұрын
помню я все таки писал комменты в коде. алгоритм был сложноватый и гдето с 3-й строчки у меня самого дымок из ушей шел и я просто даже для себя написал что вот тут я удаляю то-то для тогото и в другом месте тоже чтото написал. Синьоры которые обычно любили клевать на ревью на эти комменты не делали замечания, ну там реально сложно было понять просто читая код, ну и в итоге работал он быстро
@semyontikhonenko79377 ай бұрын
Во всех современных языках давно есть передача параметров по названию
@АндрейЧеремисин-щ7кАй бұрын
вне зависимости от того, какой флаг все время мелькает на видео, хочу сказать что автор снял отличное видео, respect +
@ЕрвандАгаджанян-в3к7 ай бұрын
Интересен тренинг по рефакторингу))
@rudolfsikorsky79007 ай бұрын
Бывает код, покрытый тестами, а у меня - код, порытый туду-шками :)
@Удалить-ю3у7 ай бұрын
"Ненужные переменные", которые сразу после получения передаются, делают для целей отладки, когда нужно понять, что именно возвращает метод. В релизном коде оптимизатор, скорее всего уберет эту переменную.
@oshastitko6 ай бұрын
да причём тут релиз. Любой "запашок кода" - это для программиста, компилятору вообще пофиг по большому счёту, как код написан, если он выполняет тоже самое. Ненужные переменные усложняют чтение и понимание, по ним непонятно, участвуют они вообще в процессе, влияют на что-то или нет
@vladbarkovsky39397 ай бұрын
меня кстати реально бесит закомментаренный код. типа, там ещё сверху написано "не трогать, оно будет надо тогда-то" причём, оно надо тогда-то уже больше года. я всегда в PR делаю пунктик в конце: "а ещё я удалил из такого-то файла 150 строк кода, который делал ничего". и всёравно мне кидают в PR комментарии "зачем ты убрал - оно будет надо".
@jakksoft7 ай бұрын
Не хватает усидчивости самому читать книгу по рефакторингу, сделайте пожалуйста видеооо, все 10 часов 3 раза пересмотрю)
@Karpick_ds7 ай бұрын
Эх, Сергея Немчинского больше не зовут «всё ещё Сергей Немчинский» (( Ушла эпоха
@mykola-rohoza7 ай бұрын
За тренинг по рефакторингу двумя руками
@WSSAWERАй бұрын
Длинные методы. Любой длинный маталгоритм даже в ненагруженной среде будет больше страницы. Так же бывает с теми вещами, что обрабатывают большие данные из-за требований к скорости. Свитч-кейс - один из самых удобных инструментов. Во многих языках это так же хороший способ типизации и проверки условий(например, в шарпе). Гораздо лучше читаемый. Про проперти тут уже говорили. Для загрузки файла конфигурации - очень частое явление. Но бывает и, например, указание параметров точки. Это уже несколько разнотипных параметров(координата, вращение, параметрытекстуры, направление). Создавать отдельный не функциональный класс только для передачи данных, выдавать его в общем контексте(namespace) для передачи данных? Это же те самые сгустки данных... Локальные переменные полезны для отладки. Если часто нужно - можно и так оставить. Многое из этого - вообще мелочи) С улучшением языков и IDE книги устаревают, и именитые разрабы за ними часто не успевают. А в целом - отлично)
@torrvic11567 ай бұрын
Большое спасибо за то, что делитесь знаниями, Сергей! Но вот про свич всё-таки некоторые опытные программисты говорят, что он не так уж и плох. Конечно же хотелось бы ваш рассказ про рефакторинг :) Читать влом))
@oshastitko6 ай бұрын
"свитч не так уж и плох" может быть только для совсем примитивных вещей, когда, например, записать разные строки в зависимости от значения в какой-нибудь условный лог (и не более) проще, нежели городить и внедрять ещё одну сущность и только в том месте, которая гарантированно будет всегда простой как двери и не требующей тестирования. Тогда, может быть, допускается этот свитч (и то, я не сторонник его, потому как иногда даже совсем простые вещи начинают разрастаться, требуют изменения в старый код и провоцируют регрессивное тестирование)
@dmitriy92326 ай бұрын
Даешь тренинг по рефакторингу! ))
@ПавелМароков-э8л7 ай бұрын
я программист-любитель. но когда мне нужны были просто координаты - я создал класс с переменными X, Y и сеттерами/геттерами. мне это показалось очевидным! сам додумался! ))
@simpleman66177 ай бұрын
К многим из приведенным здесь советам я допер сам методом проб и ошибок набивая себе шишки-это издеьржки того что я самоучка. Тише едешь дальше будешь - если не торопясь дапшь осмысленные имена переменным если не полениться и вставить коментарий - потом будет проще. Еще много зависит от языка - помню на бейсике была такая каша...
@miminorka7 ай бұрын
вообще очень категорический совет и уж точно неприменимый ко всем ситуациям, повторение (копирование) кода вполне нормально к тем местам, где мы уверенны что логика будет другой, в тех же местах где нам надо чтобы логика была той же, но обьекты другими, надо переделывать под дженерики а не копировать
@oshastitko6 ай бұрын
если у вас есть похожая, но не точно такая же логика, то это повод вычленить из неё идентичные участки, создать базовый (скорее всего, абстрактный) класс, реализующей эти участки (хотя в последней версии шарпа можно и в интерфейсах писать логику :) ) и в классах-наследниках уже реализовать различия, реализовав соответствующие абстрактные методы, а не городить 2 похожих кода в разных местах
@kasparzubarev7 ай бұрын
Если вы пишете на С то полезным будет посмотреть на то как организованы "конструкторы" структур в исходниках ядра Linux. В некоторых драйверах применяются принципы аналогичные принципам используемым в ООП, особенно в драйверах работающих с видеоподсистемой V4L2. Можно много занимательного почерпнуть
@ВячеславСергеевич-у1н7 ай бұрын
Я добавил бы следующее к code smells: 1) это создание объектов, классы которых реализуют один и тот же интерфейс, через new. Лучше использовать аннотации + рефлексия и создавать объекты в ObjectFactory 2) Использовать pojo классы, сформированные на основе json, вместо этого использовать JsonObject или String + jsonPath
@AlexeySukharenko7 ай бұрын
Я бы еще к плохому коду отнес лишком длинные классы
@randomisgood26197 ай бұрын
Ура, новое видео!
@mrbshorts60027 ай бұрын
Не могли вы снять видео что должен знать джуниор с++
@romanalexandrov28807 ай бұрын
Раньше, когда я что-то переделывал в коде, то заодно сразу рефакторил и закомменченые части - и даже так они мне ни разу не пригодились =D С тех пор, как это заметил, удаляю их без тени сомнения
@darkart64877 ай бұрын
Да я так хотел зарефакторить крафт и готовку. В общем всё вроде нормально объединил, но суть до дела полается нужны другие переменные чтобы показать отличия. Код становится непонятной лапшой. Вывод лучше пусть код повторяется, чем он становится непонятным с первого взгляда
@ДенисДенис-в3э7 ай бұрын
Спасибо большое за Ваши видео. Прокомментируйте пожалуйста Apple Vision Pro, какие перспективы Вы видите, какой язык понадобится для разработки приложений под Vision Pro. Спасибо !
@SergeyNemchinskiy7 ай бұрын
перспективно. Свифт
@СергейМитяев-п1н7 ай бұрын
"одноразовые переменные" использую при отладке, если получаемый объект зависит от времени, или сложно конструировать.
@nicolas267s7 ай бұрын
9:05 Я как-то раз дебажил код, в котором один метод отвечал за сразу за чтение, создание, обновление и удаление (!!!) сущностей, в зависимости от набора параметров. Вишенкой на торте было то, что метод, к тому же, вызывался из десятков разных мест. И нет, там не было просто параметра типа action, туда передавалось с десяток разных параметров и всё это иффалось по - "пойди разбери какой" логике. Сам баг заключался в том, что при открытии определённой страницы из базы пропадали данные(кто бы мог подумать...). Естественно я не стал продолжать эту вакханалию, не стал просто подбирать параметры, а разделил все эти функции по своим методам. Тут и список параметров резко сократился. Надеюсь у автора этого кода уши горели, пока я этот клубок распутывал.
@PerfectHolyPervert7 ай бұрын
Спасибо за рекомендацию по поводу книги по рефакторингу.
@diatm15067 ай бұрын
Сергей что Вы думаете о книге Khalila Stemmlera The Software Design & Architecture Handbook?
@D1LLERH7 ай бұрын
А где Сергей Немчинский? Он вернётся?
@__ali__977 ай бұрын
Та самая тонкая грань, между дублированием кода и принципа SRP, как понимать когда нужно реюзнуть уже имеющийся код, а когда нужно написать похожий код, но использующийся в другом месте с похожей, но не точно такой же логикой.
@oshastitko6 ай бұрын
если у вас есть похожая, но не точно такая же логика, то это повод вычленить из неё идентичные участки, создать базовый (скорее всего, абстрактный) класс, реализующей эти участки (хотя в последней версии шарпа можно и в интерфейсах писать логику :) ) и в классах-наследниках уже реализовать различия, реализовав соответствующие абстрактные методы, а не городить 2 похожих кода в разных местах
@pash0k137 ай бұрын
"12:44 - ненужные примитивные переменные" - вот не согласен. есть еще простота и читаемость кода. если будет метод, и в этом при вызове метода для передачи значений вызываются еще методы, несколько, - то можно глазки сломать. пример foo(foo1(value1, value2), foo2(value1), foo3(value1, value2, value3)); 👀. уф... если спуститься на уровень ниже - то все равно создается область в памяти, которая содержит результат выполнения метода и затем передается в метод. если создать переменную для сета в метод - то эта переменная будет указывать на результат выполнения метода и затем этот результат будет передан методу который нуждается в этой переменной. в таком случае читаемость кода возрастает в разы. в итоге: не всегда нужно избавляться от переменных которые потом используются в одном месте. как вариант, когда нужно избавиться - если в методе есть переменная, а потом она же возвращается значение из метода - то да, тут хорошо срезу результату делать ретурн.
@SergeyNemchinskiy7 ай бұрын
я и не говорил - всегда
@pash0k137 ай бұрын
@@SergeyNemchinskiy да, но в контексте будто бы подразумевается 'всегда'. ще раз дякую за мувік!
@Petrovi_-tv5et7 ай бұрын
Здравствуйте , можете пожалуйста обьяснить на простых словах про DOM JS ? Спасибо
@MaximKacc7 ай бұрын
Да уж, индусы нынче switch-case'ом пишут)
@Vlad-ok8wp7 ай бұрын
Коли вкотре чую що метод повинен буту не більше строрінки, так і хочу показати це відіо своєму шефу. В мене на фірмі код в 1000 строк це норма, максімально здається десь біля 2000 . Колі я почінаю працювати с новим для мене методом, пару годин може знадобитись щоб зрозуміти як це працює.
@perekhrestdimon7 ай бұрын
Вопрос: Если я учусь по видео и делаю по ним проекты, смотрю, что делает автор, и повторяю за ним, и так делаю сайты, это копипастинг? Стоит так делать, или лучше делать самому? Спасибо заранее!
@SergeyNemchinskiy7 ай бұрын
Это нормально для начала учебы, но уже пора начинать делать все самому
@azamjon407 ай бұрын
Я удалаю тоже, даже не принимаю такой код )))
@zarazlik7897 ай бұрын
Даешь тенинг
@РоманОболонский-ц8н7 ай бұрын
На счет мертвого кода, который никто не юзает. Если не ошибаюсь, то компилятор детектит такие куски кода и выкидывает их
@Александр-о5о3й7 ай бұрын
Дело не в компиляторах, а в том что человеку не удобно.
@miminorka7 ай бұрын
вобще с такими радикальными методами без рассмотрения других вариантов это конечно же экстремизм
@oshastitko6 ай бұрын
в чём радикализм?
@olegoleg1357 ай бұрын
Про "закомментированный" код улыбнуло. Каждая нормальная IDE поддерживает сворачивание блоков кода любого размера, так что это точно не должно являтся проблемой. Также иногда бывает полезным оставлять такие блоки, чтобы в дальнейшем понимать, как возникла новая версия этого блока. Например, какой-то сложный алгоритм, который был изначально реализован в каком-то методе, потом этот метод был существенно переделан, но без старой версии этого метода трудно понять(если вобще возможно), почему именно так в последствии был реализован алгоритм в данном методе.
@oshastitko6 ай бұрын
Если новая версия без старой не читается - то, скорее всего, у вас не очень хорошо реализована новая версия. Это скорее повод для рефакторинга, а не повод оставления старого и, скорее всего, уже неработающего кода. Если понять всё равно тяжело - значит, у вас метод взял на себя слишком много, дробите его. Резюмируя: желание оставить старый код прежде всего говорит о проблемах в новом коде
@alekseyshibayev52437 ай бұрын
Сергей, давно вы современный код не видели, особенно сеньерский. Java превратили в паскаль. Кругом инжект очередного бла-бла-бла-Service, var и перегруженные цепочки функциональщины.
@SergeyNemchinskiy7 ай бұрын
да видел
@miminorka7 ай бұрын
копирование кода оправдано 100 если заранее известно что он будет работать отлично от исходного, и в этом случае копировние оправдано, об этом нужно сказать
@shurko7 ай бұрын
Не надо тренинг.
@krivodeling79252 ай бұрын
+
@СергейНасакаев-п1ь7 ай бұрын
Конечно, братан, всё нужно: " робить будем пока не помрём." Как говорил один "ИЗ": " куй железо, не отходя от кассы!".
@СергейНасакаев-п1ь7 ай бұрын
А ещё:" полян'ыца". Всё.
@VitalySem7 ай бұрын
Що за напівміри? Пахне, попахує, він смердить))
@Feelmeee-p6s7 ай бұрын
Непонятно что за символ в левом верхнем углу переливается двумя цветами🤔🤔 404
@ЭлайтСолт7 ай бұрын
Все гораздо проще! Как сказал один великий программист: Если твой код работает корректно и выполняет свой функционал,значит - это хороший код. Все остальное второстепенно
@nicolas267s7 ай бұрын
Типичная ошибка новичка. Любой код рано или поздно ломается, или его приходится дополнять. Если новому разработчику приходится в твоём коде неделями ковыряться, чтобы разобраться, то это плохой код.
@ЭлайтСолт7 ай бұрын
@@nicolas267s Это не мои слова, это слова программиста Маркуса Перссона.
@sergiisuprun7 ай бұрын
Читать книги, когда IDE все подсвечивает и подсказывает, вы серьезно?
@SergeyNemchinskiy7 ай бұрын
угу
@itlife87927 ай бұрын
еще бывает оставляют, старый код закоменченным (прям огромными блоками), или вешают @Deprecated с ссылкой. на новый метод, но я сторонник удалять такое, хотя кто-то оставляет @Deprecated методы, чтобы понять, какой метод пришел на замену
@andreasstager16427 ай бұрын
В большинстве нормальных компиляторов есть tree shaking, который отбрасывает неиспользуемый код. Как код, который никто никогда не вызывает, может приводить к ошибкам, для меня вообще загадка.
@sergeypekar10587 ай бұрын
Еще как может. У меня такое было не один раз когда я начинал использовать какой-то легаси класс (который, кстати, как легаси никто не пометил(, а потом, оказывалось, что он уже давно устарел и нужно было использовать другой. А все потому, что кто-то решил, что это хорошая идея - оставить старый код в проекте
@vanstrihaar7 ай бұрын
Лайт-вариант - новички могут посмотреть и решить "раз есть - значит норм", и делать похоже.
@nicolas267s7 ай бұрын
Очень просто может, хоть на этапе компиляции, это проще исправить, хоть при запуске. Например, если зависимый код был изменён. Даже если его в рантайме никто не вызывает, он может загружаться при инициализации и кидать исключения.
@vanstrihaar7 ай бұрын
Я стараюсь избегать использование вызова метода в качестве параметра, только в простых случаях. А когда в одной строке вызовов методов 3 и больше - код может тяжело читаться. С другой стороны имя промежуточной переменной может помочь в понимании кода.
@sergeiseivach7 ай бұрын
Совершенно верно, и брейкпоинт поставить на промежуточную переменную - тоже удобно. Как говорит один известный IT-блоггер: любой дурак может написать код, понятный компьютеру. Хороший программист пишет код, понятный человеку
@oshastitko6 ай бұрын
скажем так, лично я не ставлю себе рамок и пишу и так, и эдак в зависимости от "интуитивной необходимости". И да, это единственный аспект в видео, с которым я в чём-то не согласен
@AlexesUA7 ай бұрын
Мені точно сподобався би тренінг по рефакторінгу. Та й відео на ~20 годин зайшло би. 20 годин розслабляючого голоса Сергія.... Каєф... 😅
@Carrergt7 ай бұрын
Так буде цікавим. Можливо буде наступним після GRASP and GOF
@MsSmartFox7 ай бұрын
"тимчасові" змінні стануть в нагоді коли ти будеш дебажить код. Замість того щоб визивати метод який повертає значення у code evaluation вікні, ти просто стаєш на потрібний рядок дебагером та дивишся шо метод повернув, та що ти передаєш далі.
@SergeyNemchinskiy7 ай бұрын
Взагалі-то будь який дебагер дозволяє подивитись результат визову метода. А ще, краще намагайтесь юзать логуванне + юніт тести заміст дебагга
@PEREPELITSA_KIRILL7 ай бұрын
Прекрасное видео ещё одна хорошая книга в копилку. Спасибо Сергей пойду читать. А на счёт тренинга да хотим и курс по java тоже а что нет)
@illia42287 ай бұрын
Тренинг по рефакторингу интересен!
@profile_pub1907 ай бұрын
Ещё бы к запахам кода отнёс void метод get, который что-то изменяет, и метод set который возвращает какое-то измененное значение, и их комбинация когда пропускают промежуточные переменные и в аргументы метода get передают возвращаемое значение метода set 😂 и это не придумано, а описание случая из жизни
@SergeyNemchinskiy7 ай бұрын
да ну нахер :) остановите землю, я сойду
@profile_pub1907 ай бұрын
@@SergeyNemchinskiy земля в безопасности - было переписано, ускорено и сейчас только история гита хранит упоминание об этом
@oshastitko6 ай бұрын
у вас уже прям какие-то извращения.... 😀
@profile_pub1906 ай бұрын
@@oshastitko доводилось переделывать плохо пахнущий (и работающий) код. В одном случае был труд индийской студии и там транзакция в БД ждала ответа платежного сервиса :D
@andreasstager16427 ай бұрын
Parameter object - костыль для языков, где нет named-параметров. Надо было бы сделать на этом акцент.
@HelloWorld-ln5cy7 ай бұрын
Обьясни что такое named- параметры, а то не понятно о чем ты.
@andreasstager16427 ай бұрын
@@HelloWorld-ln5cy Смотри например Dart.
@_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-ln5cy7 ай бұрын
@@_dzen_tv_ а понял, это не особо решает проблемы, да код немного читаем становится, в c# есть то что вы описали, но это не особо популярный подход, куда проще вместо кучи параметров передать один обьект или структуру и не морочить голову, особенно если эти данные постоянно используются вместе, по типу векторов, проще передать структуру чем три параметра по отдельности. Автор ролика именно о таком и говорит.
@_dzen_tv_7 ай бұрын
@@HelloWorld-ln5cy тут есть нюанс get_users(UserFilter(param0=0, param1=1, ...)) против get_users(param0=0, param1=1, ...) Другое дело что архитектурно get_users будет расположена на слое репозиториев, а UserFilter будет определён где-нибудь в файле filters.