3:14 я бы тут поспорил, длина имени переменной напрямую зависит от времени ее жизни(величины контекста) => "l" отлично подходит, вот если бы у тебя стрелочная функция состояла строк так из 10 и больше, тогда уместно было бы использовать "location"
9:15 может показаться что геттеры и сеттеры нужно использовать всегда, я сначала так и подумал) Это справедливо для языков типа php, c# или java. Но в js можно их добавлять тогда, когда будет нужно
Хорошие советы, спасибо. Единственное, что бросилось в глаза: функция isActiveClient (ua-cam.com/video/XT6XkIJIVbA/v-deo.html) далеко не такая простая, как может показаться из её названия. Выглядит как функция, которая «залезет» в переданный объект и проверит одно-два поля; но на самом деле реализация «идёт» в базу за записью и проверяет уже полученные из базы данные. С separation of concerns и single-responsibility principle у этой конкретной функции не очень.
Более того, в этом примере вместо одного цикла forEach теперь появился второй цикл (filter). Почему было не оставить один foreach, в котором if(isActiveClient) вызывать?
5:08 - как по мне, версия, обозначенная "Bad", читается куда легче и она решает одну конкретную задачу - выполнение email для всех активных пользователей. Дальнейшая декомпозиция излишня. Кроме того, когда тебе дают чужой проект на 120 файлов, хрен найдёшь этот isActiveClient, его наоборот надо компоновать, а не разбивать. Главные принципы декомпозиции в том, чтобы: - метод был читаем, - были понятны зависимости, - описание всего метода помещалось на одном экране Остальное - это прихоти. 6:19 - Как раз при масштабировании и надо пристыковывать дополнительные функции, вместо внедрения дополнительной логики в первичную. Например есть у вас функция валидации формы. Изначально в ней были только текстовое поле, поле телефона и область текстового ввода. И вы изначально сделали просто одну проверку телефона. Добавилось у вас поле mail и вот тут надо не пихать свитчкейс в функцию валидации, а вынести проверку телефона и mail в отдельные функции, пристыковав их к первичной. И не надо писать отдельную функцию для получения введённых данных, ссылаясь на SRP. Это самый простой пример. 6:52 - Отрицаний бояться - в логику не лезть. Всегда старайтесь писать условие так, чтобы then был короче else, если else предполагается. Конкретно в этом примере Bad не потому, что отрицание в условии, а потому, что функция возвращает значение, которое для наличия then нужно инвертировать. Сам пример говорит о том, чтобы не допускать двойного отрицания.
@@drak0an а что тут разворачивать? С нарастанием кода в then может быть запихано ещё несколько десятков строк, включая дополнительные условные операторы со своими else. И чтобы при просмотре кода не пытаться понять, к какому if относится тот или иной else, желательно, чтобы if и его else находились как можно ближе друг к другу. В противном случае единственным способом понять, к какому if относится интересующий вас else, станет скрол туда-сюда и поиск нужной строки. Да, есть подсветка границ блока, но она может скосячить, да и придётся заново искать нужные скобки каждый раз, возвращаясь к этому блоку. Да, есть масштабирование окна редактора, но редактировать код, когда размер символа 5-8 пикселей - такое себе. Куда проще, если if и его else находятся на одном экране. Если же логика подразумевает какие-то операции ТОЛЬКО в случае соответствия условию, то тут и else не нужен.
Более полная информация из видео Оригинал на Анг: github.com/ryanmcdermott/clean-code-javascript Перевод на русский: github.com/ryanmcdermott/clean-code-javascript
а функция которая сейчас занимает 10 строк, через год может стать 10 функциями. в общем сами по себе правила вроде понятные, но выводы на основе них можно сделать неоднозначные и обязательно понимать, что это не догма, вот только так и не иначе.
5:30 "Не используйте флаги как аргумент функции". Goog не делает то же самое что Bad. Собственно пропущена функция проверки. А когда она будет написана, она будет вызывать две функции и передавать им аргумент имя. Который надо иметь в той же области видимости, что и флаг. И так мы ничего не выигрываем (ну кроме двух названий функций, что часто бывает хорошо, но речь шла не об этом)
Не совсем так. В идеальном мире нужно создать 3 функции. 2 исполняют какой-то код, а 3-я принимает флаг и в зависимости от него вызывает либо первую, либо вторую. Но на реальных кейсах это игнорируется и всё выполняется в рамках одной функции
@@YauhenKavalchuk Потому что оптимизация ради оптимизации - зло. Так и тут, чисто с человеческой точки зрения - только больше запутаешься.. 3 функции, вместо одной, чтобы проверить флаг.... ну бред же) Такими темпами можно до целого отдельного сервиса с API дорасти, чтобы флаг проверить или парочку))
@@ЮрийГребенюк-ы6у много книг и документаций рекомендуют время представлять как колво часов в дне * кол минут в часе * кол секунд в минуте * кол миллисекунд в секунде. Дополнительной нагрузки это не вызывает, но сразу виден процесс получения числа.
@@ЮрийГребенюк-ы6у потому что: 1) возможность модификации (вот нужно тебе будет заменить 24 на 8 или на 11 в каком-нибудь калькуляторе рабочего времени для сбора статистики - подставил изменяемую переменную и не надо "const MILLISECONDS_IN_A_WORK_DAY = MILLISECONDS_IN_A_DAY / 24 * 11") 2) читается лучше 3) ошибиться не получится
7:10 - создавать дополнительный интерфейс вместо сигнатуры функции - ошибка по бритве Оккама. Не вижу проблемы для линтеров указывать на неиспользуемые аргументы, кроме того, линтеры могут указать на недостаток аргументов при использовании этой функции. И не могут этого сделать при передаче всех аргументов как свойства объекта
@@YauhenKavalchuk Ну, опять же, я может быть не знаю достаточно JS. Но в других языках это выглядит, будто на метод build - будет возвращаться один и тот же инстанс объекта. В контексте билдера - так быть не должно. Билдер - пораждающий паттерн, и при методе build - должен возвращаться новый экземпляр. Может быть в JS - по другому - и будет возвращена копия, но я что-то сомневаюсь. Так вот, если я таки прав и возвращается один и тот же инстанс - воспользовавшись в двух местах программы одним и тем же "билдером" из примера - программист получит очень веселый и довольно трудноуловимый баг, когда у него непонятно почему изменяются свойства объекта.
Очень полезное видео. Спасибо!
Пожалуйста
Ясно, чисто, понятно. Должно стать привычкой для каждого.
👍
Отличная инфа, спасибо!
Пожалуйста!
Коротко чётко и ясно =) Респект бро 🥇
Благодарю)
Очень интересно и полезно :))
Спасибо Вам!!!
Чистый код - спокойный сон!;) Как всегда, спасибо!
все четко и по делу, прям не к чему придраться! Я бы давал ссылку на данный видос девелоперам как эталон хорошего кода :)
5:05 мне верхний Bad код кажется более понятным чем второй.
3:14 я бы тут поспорил, длина имени переменной напрямую зависит от времени ее жизни(величины контекста) => "l" отлично подходит, вот если бы у тебя стрелочная функция состояла строк так из 10 и больше, тогда уместно было бы использовать "location"
9:15 может показаться что геттеры и сеттеры нужно использовать всегда, я сначала так и подумал)
Это справедливо для языков типа php, c# или java. Но в js можно их добавлять тогда, когда будет нужно
Отличное видео.
Спасибо
Good job 👏
Хорошие советы, спасибо.
Единственное, что бросилось в глаза: функция isActiveClient (ua-cam.com/video/XT6XkIJIVbA/v-deo.html) далеко не такая простая, как может показаться из её названия. Выглядит как функция, которая «залезет» в переданный объект и проверит одно-два поля; но на самом деле реализация «идёт» в базу за записью и проверяет уже полученные из базы данные. С separation of concerns и single-responsibility principle у этой конкретной функции не очень.
Более того, в этом примере вместо одного цикла forEach теперь появился второй цикл (filter). Почему было не оставить один foreach, в котором if(isActiveClient) вызывать?
5:08 - как по мне, версия, обозначенная "Bad", читается куда легче и она решает одну конкретную задачу - выполнение email для всех активных пользователей. Дальнейшая декомпозиция излишня. Кроме того, когда тебе дают чужой проект на 120 файлов, хрен найдёшь этот isActiveClient, его наоборот надо компоновать, а не разбивать.
Главные принципы декомпозиции в том, чтобы:
- метод был читаем,
- были понятны зависимости,
- описание всего метода помещалось на одном экране
Остальное - это прихоти.
6:19 - Как раз при масштабировании и надо пристыковывать дополнительные функции, вместо внедрения дополнительной логики в первичную. Например есть у вас функция валидации формы. Изначально в ней были только текстовое поле, поле телефона и область текстового ввода. И вы изначально сделали просто одну проверку телефона. Добавилось у вас поле mail и вот тут надо не пихать свитчкейс в функцию валидации, а вынести проверку телефона и mail в отдельные функции, пристыковав их к первичной. И не надо писать отдельную функцию для получения введённых данных, ссылаясь на SRP. Это самый простой пример.
6:52 - Отрицаний бояться - в логику не лезть. Всегда старайтесь писать условие так, чтобы
then был короче else, если else предполагается. Конкретно в этом примере Bad не потому, что отрицание в условии, а потому, что функция возвращает значение, которое для наличия then нужно инвертировать. Сам пример говорит о том, чтобы не допускать двойного отрицания.
Любопытно, почему "писать условие так, чтобы
then был короче else, если else предполагается."? Разверните подробнее, пожалуйста.
@@drak0an а что тут разворачивать? С нарастанием кода в then может быть запихано ещё несколько десятков строк, включая дополнительные условные операторы со своими else. И чтобы при просмотре кода не пытаться понять, к какому if относится тот или иной else, желательно, чтобы if и его else находились как можно ближе друг к другу. В противном случае единственным способом понять, к какому if относится интересующий вас else, станет скрол туда-сюда и поиск нужной строки. Да, есть подсветка границ блока, но она может скосячить, да и придётся заново искать нужные скобки каждый раз, возвращаясь к этому блоку. Да, есть масштабирование окна редактора, но редактировать код, когда размер символа 5-8 пикселей - такое себе. Куда проще, если if и его else находятся на одном экране. Если же логика подразумевает какие-то операции ТОЛЬКО в случае соответствия условию, то тут и else не нужен.
Всё верно, прям с языка снял.
Более полная информация из видео
Оригинал на Анг: github.com/ryanmcdermott/clean-code-javascript
Перевод на русский:
github.com/ryanmcdermott/clean-code-javascript
thank u
My pleasure
а функция которая сейчас занимает 10 строк, через год может стать 10 функциями. в общем сами по себе правила вроде понятные, но выводы на основе них можно сделать неоднозначные и обязательно понимать, что это не догма, вот только так и не иначе.
извините,но звук на заднем фоне сильно мешает(
Да, я уже понял что звук в видео такого формата был лишним
@@YauhenKavalchuk а мне если честно со звуком больше заходит. Вот ведь, на вкус и цвет фломастеры разные!
5:30 "Не используйте флаги как аргумент функции". Goog не делает то же самое что Bad. Собственно пропущена функция проверки. А когда она будет написана, она будет вызывать две функции и передавать им аргумент имя. Который надо иметь в той же области видимости, что и флаг. И так мы ничего не выигрываем (ну кроме двух названий функций, что часто бывает хорошо, но речь шла не об этом)
Не совсем так. В идеальном мире нужно создать 3 функции. 2 исполняют какой-то код, а 3-я принимает флаг и в зависимости от него вызывает либо первую, либо вторую. Но на реальных кейсах это игнорируется и всё выполняется в рамках одной функции
@@YauhenKavalchuk Потому что оптимизация ради оптимизации - зло. Так и тут, чисто с человеческой точки зрения - только больше запутаешься.. 3 функции, вместо одной, чтобы проверить флаг.... ну бред же) Такими темпами можно до целого отдельного сервиса с API дорасти, чтобы флаг проверить или парочку))
Делайте, пожалуйста, музыку на фоне тише, а то мешает воспринимать информацию)
В будущих выпусках учёл это
У этих правил литературная основа? Это из книги или из опыта?
Литературная, книга «чистый код»
А про html закончился курс или будут еще видео?
Ещё 2 видео. Этот четверг и следующий вторник
Да, всё это норма.
👍
лучше записывать const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000
@@ЮрийГребенюк-ы6у Не нужно считать, сложнее допустить ошибку)
@@ЮрийГребенюк-ы6у много книг и документаций рекомендуют время представлять как колво часов в дне * кол минут в часе * кол секунд в минуте * кол миллисекунд в секунде. Дополнительной нагрузки это не вызывает, но сразу виден процесс получения числа.
Да всё верно написали, математическое умножение часов/дней и т.д. Очень частно используется. Чуть позже, Добавлю этот кейс в репозиторий
@@ЮрийГребенюк-ы6у потому что:
1) возможность модификации (вот нужно тебе будет заменить 24 на 8 или на 11 в каком-нибудь калькуляторе рабочего времени для сбора статистики - подставил изменяемую переменную и не надо "const MILLISECONDS_IN_A_WORK_DAY = MILLISECONDS_IN_A_DAY / 24 * 11")
2) читается лучше
3) ошибиться не получится
на каком языке эти примеры?
JavaScript
7:10 - создавать дополнительный интерфейс вместо сигнатуры функции - ошибка по бритве Оккама. Не вижу проблемы для линтеров указывать на неиспользуемые аргументы, кроме того, линтеры могут указать на недостаток аргументов при использовании этой функции. И не могут этого сделать при передаче всех аргументов как свойства объекта
Может быть я не оч хороший знаток JS, но чет пример на 10:59 - нифига не строитель.
🤷♂️
@@YauhenKavalchuk Ну, опять же, я может быть не знаю достаточно JS. Но в других языках это выглядит, будто на метод build - будет возвращаться один и тот же инстанс объекта.
В контексте билдера - так быть не должно. Билдер - пораждающий паттерн, и при методе build - должен возвращаться новый экземпляр.
Может быть в JS - по другому - и будет возвращена копия, но я что-то сомневаюсь.
Так вот, если я таки прав и возвращается один и тот же инстанс - воспользовавшись в двух местах программы одним и тем же "билдером" из примера - программист получит очень веселый и довольно трудноуловимый баг, когда у него непонятно почему изменяются свойства объекта.
правило что функция должна делать только одно действие - ну кто это придумал? )))))))) сначала себе напридумывают правил, потом страдают.
Это не я придумал. Данное видео - это "выжимка" из книги "Чистый код" Роберт Мартин
@@YauhenKavalchuk а найдете место где это написано?