Организованное программирование | Кирилл Мокевнин
11.3K subscribers
63 photos
236 links
Как из джуниора дойти до мидла, а потом и до синьора
Ютуб https://youtube.com/@mokevnin
Связь для предложений: @kirillpublic
Download Telegram
Когда вы последний раз видели в глаза PHP? Узнаете этот синтаксис? Эх, опять курсы дописывать)
😁25🤮17😱11🔥2👍1
Я перестал использовать Copilot после 2 месяц. И вот почему

Copilot инструмент автогенерации кода, который наделал много шуму и которым пользуются программисты по всему миру. Я тоже включился в этот хайп, поигрался, попробовал переключить свой флоу работы на него и обломался. Минусы в итоге перевесили плюсы. Сейчас про это расскажу.

Сетап

За это время я использовал copilot в основном с двумя языками: php (laravel) и typescript (react). В качестве редактора nvim (сборка LazyVim на скрине). Писал и фронт и бек и тесты.

Что понравилось

Конечно Copilot выглядит как чудо. Чем более повторяющийся код, тем больше и лучше он догадывается до того, что надо сделать. Местами он показывает простые решения, до которых сам сходу не додумываешься. В целом же, на простом коде, он дает болванку, которую писать самому не очень хочется, а тут тебе все выложили. Такой код тоже требует правки, но это все равно удобно.

Почему я остановился

Но чем дальше, тем больше появлялось ситуаций, когда я понимал, что copilot мне скорее помешал чем помог.

Уменьшение продуктивности

Обычная автоматизация, которую дает редактор, вырабатывает моторную память. Не нужно сильно думать, когда автокомплит что-то подсказывает. Вставка кода происходит на автомате причем речь не только про выбор нужной реализации функции, но и дальнейший код, который понятно куда и как надо писать. Если вставляется функция, то мы оказываемся внутри ее вызова, где дописываются аргументы если они есть.

С копайлотом это перестает работать. Каждый раз когда он что-то подсказывает, нужно внимательно смотреть, что он там предлагает и даже после вставки кода проходит некоторое время на осознание того, кто я, где я и что с этим теперь делать.

Иногда я ожидаю и хотел бы простую подсказку, чтобы завершить строку текста или функцию, а вместо этого мне выдается какая-то портянка не в тему. В итоге я чаще стал зависать над комплитом и раздражаться от того, что простые действия стали сложнее.

Импорты

Отдельная тема это импорты. Копайлот вставляет куски кода без реальной связи с окружением. Если там есть какие-то символы типа классов или внешних функций, то естественно никаких автоматических импортов не произойдет. Это сбивает, потому что каждый раз непонятно, что уже импортировано, а что нет.

Ошибки

Копайлот постоянно вводит в заблуждение. Начинаешь набирать неверную команду, вызывать неверное свойство или метод, копайлот обязательно что-то подскажет из-за чего случаются осечки. Обычный автокомплит защищает от этого, потому что если его нет, ты знаешь, что сделал ошибку. В некоторых случаях его автокомплит вообще синтаксически не коректен. У меня такое было в PHP, когда вставляешь вроде что надо, а потом только замечаешь, что он в конце не поставил точку с запятой или забыл закрывающую кавычку у строки.

Итого

В коротких командах копайлот больше мешает. Обычный автокомплит + моторная память быстрее и просто приятнее, потому что не надо думать. В больших кусках кода он бывает полезен, но когда проект уже состоялся, то многое делается копипастой и так, как например в интеграционных тестах на круды. Плюс рядом есть chatgpt у которого можно спросить и покрутить какую-то тему.

p.s. А где вас раздражает Copilot?
👍93💯2515👀4👎3🔥3🤝2💩1🦄1
Чего не умеет AI и не факт что научится

Пост про Copilot привел к тому, что я поговорил с кучкой людей об их опыте с ним и вообще AI в качестве помощника. И вот, что вылезло на поверхность. Одна из ключевых задач, которые решает программист, с точки зрения кодинга, это управление сложностью через выделение новых абстракций. Программист постоянно сталкивается с повторениями и с опытом видит то, как можно этот код унифицировать, выделить в отдельный компонент, слой или библиотеку.

AI же ведет себя совершенно по другому. Он сокращает работу программиста, но ценой генерации тонны кода. Если явно не заниматься обобщением, сам он таких решений не предложит. Причем я сильно сомневаюсь, что на текущем уровне развития он сможет предложить адекватные абстракции с учетом кейсов конкретных проектов. Даже если бы он и мог, ему нужен сильный разработчик, который знает в какую сторону смотреть, какие вопросы задавать и как потом это грамотно положить на реальный код. В этом смысле AI мне напоминает wysiwyg. Открываешь исходник и видишь кучу лишнего кода.

Это приводит меня к мысли, что, в какой-то момент, в компаниях будут бояться программистов слишком сильно завязанных на AI, потому что они будут создавать тонны не поддерживаемого кода.
👍103🤔113🔥3👏2😁2
Какой бекендовый фреймворк лучше?

Мне повезло поработать на большом количестве разных бекендовых фреймворков, среди них: django, rails, laravel, spring boot, phoenix, fastify и тонне микрофреймворков. Плюс пару фреймворков разработал сам, один из которых активно использовался в продакшене. Каждый из этих фреймворков обладает чем-то, что сделано лучше чем в других, но среди них нет ни одного, который бы сочетал все плюсы. Поэтому программисты, которые пишут на каком-то одном или двух фреймворках, могут даже не знать о том, что какие-то вещи можно делать по-другому.

Я давно хотел сделать серию постов, в котором бы разбирал наиболее удачные и интересные примеры реализации тех или иных фич. Собственно почему бы не сделать этого сейчас? В общем начинаю про это писать. В этих постах будет видно, что я больше показываю примеров из rails, но не потому что я фанат, а потому что объективно там больше всего интересных решений.

Что где сделано классно?

• Rails - миграции, роутинг, шаблоны, соглашения вместо конфигурации, тесты, фикстуры, fsm, i18n, дебаг, консоль, генераторы
• Spring boot - orm, управление зависимостями
• Django - формы, админка
• Phoenix - мидлвары
• Laravel - клиентская шаблонизация через inertia.js, трансляция в ts, jobs

С другой стороны, во всех этих фреймворках есть достаточно хреновые решения, которые мешают. Про это мы тоже поговорим. И заодно обсудим разнообразные технические решения принятые во фреймворках, которые нельзя однозначно охарактеризовать как плохие или хорошие. Например:

⁃ code first vs db first
⁃ active record vs data mapper
⁃ fillable поля и mass assigment
⁃ колбеки в orm

p.s. Какие темы интересны вам в этом ключе?

Ссылки: Телеграм | Youtube | Подкаст
👍85🔥2211👎1👀1
Заблуждения программистов относительно адресов

Мы говорили о времени, теперь поговорим об адресах. Выдержка из прекрасной статьи https://www.mjt.me.uk/posts/falsehoods-programmers-believe-about-addresses/

• Почтовые индексы всегда состоят из пяти цифр
• У адреса всегда есть почтовый индекс
• Улицы всегда имеют названия, а дома — номера
• У улиц всегда есть название
• В каждом городе есть только один уникальный адрес для каждого местоположения
• Почтовые адреса всегда включают название улицы и номер дома
• Номера зданий идут подряд
• Названия улиц не повторяются в одном городе
• Адрес включает только одну улицу
• В одной стране не может быть двух городов с одинаковыми названиями

Из моего личного опыта. Жил я некоторое время в славном городе Зеленограде (Это часть москвы за пределами москвы, как калининград). Так вот в этом городе у улиц нет названий, а номер дома однозначно определяет место в городе. Это супер удобно, только в онлайне на это мало кто рассчитывает, поэтому Зеленоградцы страдают)

Ссылки: Телеграм | Youtube | Подкаст
😁36👍21🙈6🤯21
Как я положил продакшен базу на выходных
Вчера произошла эпическая история. После планового деплоя в субботу вечером (так было нужно), мне прилетело сообщение “кирилл, у нас почему-то не показываются заявки”. Наверное фильтры слетели, подумал я и пошел проверять. Фильтры не слетели. Я слегка напрягся и пошел в яндекс клауд посмотреть что там в базе. Как я и боялся, таблицы были пустыми. Причем не все, но многие. Самое интересное, что они были не просто пустыми, но у них сбросились счетчики.

Увидел я это не сразу после деплоя, поэтому было не до конца понятно, это деплой привел к удалению данных или что-то другое. Я быстро восстановил снепшот на новом кластере, благо это делается одним кликом и выполнил туда деплой заново. Какого было мое удивление, когда после деплоя база очистилась. Какого хрена подумал я, прикидывая, что могло быть причиной. В этот момент ко мне присоединился второй разработчик проекта, с которым мы весело провели 3 часа за дебагом.

Сам деплой был необычным, потому что мы выкатывали большое изменение для обработки заявок основного договора (до этого работало только раннее бронирование). Туда входило и много кода и около 40 миграций и обновления зависимостей и новая конфигурация. Но мы точно не добавляли код, который бы грохал половину базы (как нам тогда казалось, хаха).

Дальше мы полезли изучать код на предмет подозрительных вещей:

1. Логи
2. Изменения в конфигурации
3. Ишьюсы в Laravel (основной фреймворк)
4. Миграции

Ничего подозрительного не нашли, за исключением пары транкейтов в паре миграций. Но эти трункейты были на новые таблицы, в которых точно не было данных, их скорее делали даже для локального сброса, чтобы не фиксить данные в девелоперских базах после изменения структуры таблицы.

В любом случае мы решили проверить миграции, поэтому сделали следующее. Настроили систему так, чтобы за один деплой выполнялась ровно одна миграция. Дальше мы начали выполнять последовательно деплои, попутно проверяя состояние базы в конце каждого деплоя. И, вдруг, где-то на двадцатой миграции база очистилась.

Открываем миграцию, а там тот самый пресловутый транкейт, который хоть и выглядел подозрительно, но не касался других таблиц. Смотрю в логи и вижу что транкейт выполняется так: TRUNCATE marketing_discounts CASCADE. И тут я как понял. Не знаю как так получилось, но я даже не был в курсе, что у трункейта есть такая опция. CASCADE приводит к тому, что дропаются все связанные таблицы (рекурсивно) независимо от того, есть ли там данные или нет. Сказать что я был в шоке, ничего не сказать. Тут же нашелся issues в ларавеле, где выяснилось несколько интересных деталей. Мы не единственные кто грохнул базу таким образом. Собственно сам issue появился с целью того, чтобы защитить всех остальных, на что разработчики сказали сорян, обратная совместимость. Самое смешное, что подобное поведение реализовано только для драйвера постгреса, у остальных такого нет.


When you truncate tables using the laravel illuminate db builder it truncates the table as expected. However, postgresql is different because it changes the DEFAULT behavior of truncate from RESTRICT to CASCADE. This means that you can loose all your data in other "related" tables (something that doesn't happen with the other sql drivers)


И ниже смешные комментарии в духе:


3 years passed, Laravel users still truncates their entire databases...

We were also a victim of this behavior this morning, fortunately we were on a test database. Very dangerous!


Ишью кстати закрыли с поинтами что мы не будем ломать обратную совместимость и транкейт должен сбрасывать данные, а не падать с ошибкой.

В итоге мы все поправили и восстановили данные, но открыли в себе новый страх. Давно в моей жизни не было таких приключений)

ишью: https://github.com/laravel/framework/issues/35157
😱103👍96😁19🔥146🤮3🤔1🌚1🤣1
Что такое чистый код?

По горячим следам хочу сделать саммари после выпуска, который породил вопросы: “так что же делать в итоге?”.

Есть множество небольших аспектов, которые влияют на чистоту кода и которые легко поддерживать. Именование переменных, стилистические ошибки, использование стандартных инструментов и подходов и так далее. Тут ничего сверхестественного. Есть линтеры, есть статьи и книги про это.

Но есть проблема, следованием этим вещам не делает ваш код классным, он может быть написан чисто, но при этом быть костылным/бажным/решать следствие а не причину/быть не нужным/дублироваться 100 раз. Поэтому качество кода важнее, чем его стилистическая чистота. Как сделать код качественным?

Универсальный совет такой:

⁃ Непрерывно книги про архитектуру (например совершенный код, программист прагматик, sicp, htdp и другие подобные)
⁃ Работайте в проектах с высокой инженерной культурой, работайте с людьми у которых можно научиться всему этому
⁃ Изучайте языки с другими парадигмами (особенно функциональные + лиспы)
⁃ Вливайтесь в опенсорс, гарантировано поднимает уровень кодинга в небеса
⁃ Пишите тесыт на свой код (и бизнес тут не причем, ему вообще не надо про тесты говорить, хорошие тесты ускоряют процесс написания кода)

Стать крутым разработчиком читая про принцип и пытаясь их применять невозможно (позволю использовать себе именно такое слово), большая часть принципов упрощение, которое не имеет однозначной трактовки и не может быть использовано безусловно. Всегда есть контекст в котором любой принцип не работает или делает хуже.

Набор принципов и методик, которые стоит знать, но еще лучше понимать то, что за ними стоит:

⁃ Функциональное ядро, императивная оболочка
⁃ Программирование с явно выделенным состоянием
⁃ Предметно-ориентированное проектирование (DDD)
⁃ Чистота: Модели > Контроллеры > Вьюхи

Ну и набросу для, SOLID и его знание ничего не меняет в вашем коде в лучшую сторону. Но вам придется его выучить, для прохождения собесов. Про это буду отдельными постами писать.

p.s. А какие еще принципы вы бы добавили?

Ссылки: Телеграм | Youtube | Подкаст
78👍30🔥19🤮2👀1
У меня есть веселее история. В Badoo деплой был устроен так, что новые версии файлов докладывались на прод и менялась «карта» с актуальными файлами. Деплоили каждый день. Старые файлы удалялись кронами, проверкой по дате создания, через сколько-то дней. На новогодние праздники кроны потерли все файлы с прода, пока деплоя новых файлов не было…

Вот такой коммент написали мне к посту про мой фейл с деплоем. Я вспомнил еще одну веселую историю, как однажды дизайнер нам сломал продашкен. Дизайнер запустил аб тест на регистрацию в google optimize и когда он там менял блок, какой-то, то зацепил скрытое поле с CSRF, без которого бекенд думал что его ломают и отказывался пропускать запрос.

А еще разок я забыл поменять контекст куба и в один проект влил другой, который нахрен угрохал все, что я потом пару часов восстанавливал

А какие у вас были веселые истории в продакшене? Как вы или ваши коллеги его ломали?
😁27👏22👍11🌚4🤔21🫡1
Нормально ли накручивать опыт в резюме?
Последние полтора, может два года, с этой темой мощно вошел в индустрию Антон Назаров, вызвав такое бурление, что до сих пор земля дрожит. Правда сам я наблюдал за это со стороны, не участвуя и не особо вникая в то, что происходит на полях ютуба. При этом я давно хотел с ним поболтать и недавно позвал его в подкаст. Запись будет уже скоро, а пока я к ней готовлюсь, то смотрю видео, видео с Антоном, которые мне показались наиболее интересными.

Начинал я это смотреть скорее с нейтральным отношением, потому что накрутка опыта не является чем-то специфическим для его комьюнити. В штатах это давно поставлено на поток, так или иначе все это делалось то тут то там. Да, Антон придал этой теме ускорение, но я рассматриваю его деятельность как производную сложившейся экономической ситуации и подозреваю что дальше будет только больше. Не было бы его, был бы кто-то другой (и они есть, но про это меньше знают и говорят). А в “правильное” устройство мира я не верю, жизнь сложная штука, а наша задача адаптироваться и кто эффективнее и быстрее это делает, тот оказывается дальше.

В первых мотивационных видео которые я посмотрел, сложилось стойкое ощущение, что я слушаю проповедь от телепроповедника (знаете, которые в штатах выступают по телевизору). Уверен что этот образ выбран намеренно, если и не с самого начала ведения канала, но к этому пришло. Но чем дальше я слушал, тем больше становилось понятно, что за этим внешним проявлением, в общем-то все разумно. Антон не призывает ничего не знать, делать свою работу плохо и вообще быть злодеем. Все ровно наоборот, хотя чтобы это понять, нужно посмотреть разные ролики.

Мне кажется, что я могу объяснить одну сторону этой истории. Например те кто меня слушают, знают что есть темы за которые я слишком топлю. Почему именно эти темы и почему так рьяно? Можно считать это реакцией на то, что то как учатся люди и что потом транслируют повернуто в одну сторону и чтобы сбалансировать все это, нужно тянуть сильно в другую сторону. Нельзя при перекосе в одну из сторон установить баланс толкая среднюю точку зрения, приходится сдвигаться в экстремум. Простой пример, я за баланс между функциональщиной и императивщеной, но говорю больше про функциональщину и толкаю туда людей, потому что императивщины у них и без меня полно. И таким образом, в конце концов система балансируется.

При этом такой подход, конечно же, порождает перекосы на местах. Тут не поспоришь. И как бы Антон не говорил в видео “я не призывал их так делать, это их решение”, прилетать будет всегда ему, потому что кто ведет людей, всегда получает за их поступки. Я точно так же могу сказать, что некоторые ребята так много топят за то что я говорю в своих компаниях, что при имени “кирилл” их начинает трясти.

Если же смотреть на ситуацию с накрутками с точки зрения бизнеса. Я вот что понял во время просмотра. Хекслет и другие мои проекты выигрывают в такой среде от того, что мы можем и делаем процесс найма (не только девелоперов) лучше чем у других компаний. Соответственно мы работаем эффективнее и быстрее. Вот такой неожиданный вывод.

p.s. Кстати я тут организовал страничку в vk если вдруг кому интересно можно подписаться там: https://vk.com/orgprog
👍62🥴21💩18🤨7🔥64👎3🤡3😁1🤔1🥱1
Тесты до кода без TDD (твиттер-тред)

Я часто пишу тесты до кода, но при этом не работаю по TDD. Почему?

TDD подразумевает мелкое движение по функциям, которое во многом сфокусировано на внутренних модулях и юнит тестах. Такие тесты быстро приходят в негодность и требуют их постоянного переписывания, что, вообще говоря, мешает разработке, так как нужно постоянно их перерабатывать.

Что еще хуже. Фактически TDD, в таком виде, уводит от главной цели тестирования – максимально дешево убедиться в том что код выполняет свою задачу ради которой он вообще пишется. В итоге программист незаметно для себя начинает думать не о пользователях, а внутренних деталях

На практике же, в бекенд фреймворках или библиотеках все часто сводится к очень небольшому публичному апи (функция, маршрут (роут), класс), протестировав которое, никогда больше не придется менять тест. При этом получается высокая гарантия работы и возможность легко менять внутренности

При таком подходе один раз написанный в начале тест никогда серьезно не поменяется, кроме случаев полной переработки апи, что бывает редко. И вот такой способ, позволяет значительно ускориться во многих ситуациях, особенно там где сложный вход/выход и много состояний.

Дальше зависит от специфики. В библиотеках лучше писать тесты до кода почти всегда, это дешево и быстро, в бекенд фреймворках такое можно писать почти всегда без ущерба, а вот во фронтенде тесты до кода это мука. А tdd там просто злое зло, кроме либ и логики вне представления

Из последнего примера. Последние три месяца мы разрабтывали систему приемки документов от студентов, в которой в итоге сотня роутов, 68 моделей и около 50 тысяч строк кода (laravel/php + react/ts). Понимание доменной области приходило в процессе кодинга, поэтому можно сказать что мы двигались немного в слепую, дорабатывая систему по ходу. И я сошел бы с ума делая все это без тестов, так как проект часто менялся, но сама модель нет, скорее происходило расширение и иногда расщепление сущностей. Мы написали около 300 интеграционных тестов, которые выглядят примерно так:


#[Test]
public function store(): void
{
// TODO: check for new college without templates
$uploadedFile = UploadedFile::fake()->create('file.txt');
$attrs = Arr::except(ContractTemplate::factory()->raw(), ['college_id']);
$body = [
'college_contract_template' => [
...$attrs,
'uploaded_file' => $uploadedFile,
],
];

$response = $this
->actingAs($this->owner)
->post($this->route('college.admin.contract_templates.store'), $body);

$response->assertSessionHasNoErrors();
$response->assertRedirect();

$template = $this->college->contractTemplates()->latest()->first();
$this->assertModelExists($template);

$this->assertFieldsEqual($attrs, $template);

$this->assertModelExists($template->file);
Storage::assertExists($template->file->path);
$this->assertEquals($uploadedFile->name, $template->file->file_name);
}


Сами тесты менялись редко, но регулярно дописывались для проверки все новых правил. Сейчас в систему очень легко вносить изменения и рефакторинг не доставляет боли.

И вот что по этому поводу сказал Kent Beck (спойлер: мне платят не за тесты) https://gist.github.com/jordelver/3818839

p.s. Какое соотношение тестов к коду в вашем проекте?
👍2611🤔6👎1
Немного отвлеченный пост. Слухи о том что ютуб могут отрубить становятся все громче, поэтому я начал активнее развивать сообщество в VK. Не знаю как оно пойдет дальше, но если вы сидите в вк или рассматриваете его как запасной аэродром, то обязательно подпишитесь https://vk.com/orgprog Помимо прочего, там удобно слушать видео выложенные в виде подкастов. Кстати, по идее, сегодня будет следующий выпуск. Анонсирую когда зарелизим.

И исчо) я решил по полной вкладываться в развитие сообщества программистов, которые хотят дойти до топовых позиций. Контент будет немного смещаться в сторону помощи работающим девам на начальных и мидл позициях вырасти через прокачку продуктового мышления (бизнес + маркетинг + продукт), через технический рост без булшита (учим то что реально помогает и нужно в повседневной работе). По пути возможно появление каких-то воркшопов, курсов и даже консультаций. Поделитесь в комментариях, насколько вам это интересно. Всем чмоки!

Ссылки: Телеграм | Youtube | Подкаст
🔥187💩5229👍19👎9🤮6🤔3🆒3🥱1🖕1
Организованное программирование | Кирилл Мокевнин pinned «https://www.youtube.com/watch?v=ImHSnB-uLd4 Второе видео на моем канале, где мы с Мишей Фесенко обсуждаем инжиниринг в букинге. Миллионы строк на перле, тысячи факсов, зарплата, найм, культура devops и многое другое!»
Воу, неожиданно сегодня вышел выпуск со мной в мы обречены https://www.youtube.com/watch?v=40QghvScTew

> В первом после долгого перерыва выпуске наши авторитетные эксперты составили для вас список из 10 языков программирования, которые в 2024 году являются самыми высокооплачиваемыми и востребованными на рынке.

Кажется неплохо получилось и самое прикольное что мы все втроем у кого брали интервью говорим разные вещи) Вроде все записи вышли, переключаюсь на свой контент послезавтра!
🔥31👍8🤡4❤‍🔥2🤔21
Совершенный код: отделяем получение данных от их использования

Есть такой код, который я называю "код, который заставляет себя переписывать". Этот код не выглядит плохо и про него нельзя сказать сразу, что он делает что-то плохое. Проблемы проявляются позже — в тот момент, когда нужно внести изменения либо отладить его.
Рассмотрим пример. В проектах Хекслета студенты часто пишут подобный код:


document.getElementById('spinner').classList.add('d-none');


На первый взгляд ничего криминального. Здесь извлекается DOM элемент с идентификатором spinner и затем к нему добавляется новый класс d-none. Теперь представьте, что кроме добавления нового класса, нужно удалить старый. В таком случае код выше часто переписывают следующим образом:


document.getElementById('spinner').classList.add('d-none');
document.getElementById('spinner').classList.remove('d-flex');


Да, не все его так напишут. Но, всё же, как показывает практика, многие просто скопируют строчку и поменяют только последнюю часть. Сразу бросается в глаза, что произошло дублирование. Причём работа с DOM — недешёвая операция. Такое дублирование приводит к замедлению кода, иногда значительному.

Посмотрев на этот код, можно подумать, что это косяк того программиста, что выполнил дублирование. Отчасти это так, но проблема глубже. Исходная строчка была написана так, что она "заставляет" переписывать код при любом повторном обращении. В этом коде выполняется сразу две операции:

• Извлечение данных
• Манипуляция данными

Как правило, первая операция делается ровно один раз, а вот манипуляций может быть много. Причём обычно они появляются не сразу, а накапливаются в процессе жизни кода. Это значит, что код в любом случае придётся переписать.
Поэтому всегда стоит сразу разделять получение данных и их использование:


const spinnerElement = document.getElementById('spinner'); // получение
spinnerElement.classList.add('d-none'); // использование


Не стоит беспокоиться, что кода станет на одну строчку больше. Это тот самый случай, когда "больше — лучше". Во-первых, у выбранных данных появляется имя (переменная). Благодаря именованию сразу понятно, что это такое, с какой сущностью имеем дело. Во-вторых, в этом коде не появилось дополнительной логики. И он легче читается. Ещё один плюс — проще отладка.
Ниже ещё примеры, которые я извлёк из реальных проектов специально для данной статьи.


// Неправильно
const { output } = state.fileTabsInfo.tabs.find(tab => tab.id === 'output').result;

// Правильно
const outputTab = state.fileTabsInfo.tabs.find(tab => tab.id === 'output');
const { output } = outputTab.result;

// Неправильно
const html = document.querySelector('#alertBox').innerHTML;

// Правильно
const alertElement = document.querySelector('#alertBox'); // получение
const html = alertElement.innerHTML; // использование

// Неправильно
const name = User.find(5).getName();

// Правильно
const user = User.find(5); // получение
const name = user.getName(); // использование

// Неправильно
const newUrl = `${url.parse(address).protocol}//${url.parse(address).host}`;

// Правильно
const urlParts = url.parse(address);
const newUrl = `${urlParts.protocol}//${urlParts.host}`;


p.s. Домашнее задание: поправьте в своем проекте 2 места, разделив получение данных и использование

Ссылки: Телеграм | Youtube | Подкаст
👍57🐳54🔥119👨‍💻2👀2💩1
Партнерка Хекслета и Волчья стая

Вчера произошел курьезный случай в канале Антона Назарова, куда он запостил вот такое https://t.me/m0rtymerr_channel/1646 с вопросом, как вы думаете кто это? Мне стало интересно и я пошел посмотреть комментарии. Там начали называть, в том числе, школы и в какой-то момент промелькнул Хекслет. Как интересно подумал я, пока ниже не увидел ответ Антона “это они”. Я аж подпрыгнул на этом моменте. Внутри компании нет людей, которые занимаются подобными механиками продвижения, поэтому я сразу написал в рабочий чат, чтобы узнать что происходит.

В общем совместный ресерч + доп инфа от Антона показали, что это веб-мастер, который зарабатывает на партнерских программах. Наша партнерка добавлена через популярный на рынке https://advcake.com/ где тусует большое количество веб-мастеров, которые, как правило, привлекают трафик через свои сайты, например рейтинги курсов.

Неприятно то, что он в личке Антону представился как сотрудник Хекслета, что конечно же не правда. Но хорошо что, разобрались. Приятно, то что аудитория Антона Хекслет знает и знает про его репутацию, потому что в комментариях это многих удивило. Будте на чеку. Я уверен что этот веб-мастер пошел много куда + он не один такой.

p.s. На следующей неделе выйдет видео с Антоном, которое мы с ним недавно записали. Подпишитесь на ютуб https://www.youtube.com/@mokevnin/featured чтобы не пропустить ;)

Ссылки: Телеграм | Youtube | Подкаст
👍5812😱9🤡7🤯2🐳1🤣1
5 советов по проектированию функций, которые значительно улучшат ваш код (твиттер-тред)

Обычно, от функций ожидают сокращения дублирования кода. Да, функции устраняют дублирование, но лишь в дополнение к тому, зачем они нужны. Настоящий смысл функции – повышение уровня абстракции. Звучит немного абстрактно, поэтому раскроем подробнее

Мир сложная штука, но эта сложность спрятана за простыми и понятными вещами. Например, работать с клавиатурой может даже ребенок, но лишь потому что она хорошо спроектирована и прячет от нас детали реализации. Нам не нужно знать физических законов для ее использования

Клавиатура, в свою очередь, состоит из деталей, которые тоже имеют достаточно высокий уровень абстракции: микросхема, мембраны, корпус, индикаторы. Все это на поверхности и достаточно далеко от реально протекающих процессов внутри

То о чем мы говорим, называется слоями абстракции. Любую систему можно разбить на набор слоев, в которых каждый следующий слой, строится на базе предыдущего слоя, что создает ощущение простоты. Мы не думаем о системе до самой глубины, нам достаточно знать про текущий слой

Из этого вытекает логичное, но, почему-то, редко обсуждаемое правило. На самом верхнем уровне, проектирование кода должно идти от слоев, которые 1) имеют четко выраженную ответственность 2) оперируют только абстракциями более низкого уровня 3) не прыгают через уровни

В самом общем виде эта мысль описана в SOC https://en.wikipedia.org/wiki/Separation_of_concerns… Примерами здесь служат: модель OSI, HTML/CSS, Миксины и многое другое. Это очень близко нашей теме, хотя и не один в один. Плюс хорошая адаптация к коду от Мартина: Принцип Single Level Of Abstraction

Возникает вопрос, а на что конкретно ориентироваться чтобы создавать функции хорошо? И у меня есть ответ. Существует довольно много простых и не очень принципов, которые определяют как лучше проектировать функции. Большая часть из них универсальна и подходит для всех языков

Начнем с самого главного правила в программировании: отделение чистого кода от кода с побочными эффектами или "функциональное ядро и императивная оболочка". Чтобы понять о чем тут идет речь, поговорим о том, что такое чистые функции.

Чистая функция – детерминированная функция, без побочных эффектов. Детерминированность означает возврат одного и того же результата на один и тот же вход в рамках одного запуска программы. При следующем запуске результат может быть другим, но постоянным до остановки.

Побочные эффекты – влияние функции на внешнее окружение: модификация глобальных переменных, аргументов переданных по ссылке, ввод/вывод (чтение и запись файлов, сеть, консоль и т.п), вызов внутри себя других функций с побочными эффектами

Чистые функции имеют непосредственное отношение к понятию "бизнес-логика", алгоритмической части программы, которая занимается сутью бизнеса, ради которого она написана. Например много логики в автопилотах, бухгалтерском софте, логистическом, банковском и так далее.

Эта логика, сама по себе, не имеет отношения к коду. Она, часто, существует на уровне документов и спецификаций, ее понимают заказчики бизнеса и ради нее, собственно, софт и пишется.

А выполнение HTTP-запросов, взаимодействие с базой данных, запись и чтение файлов, все это обвязка, которая интегрирует логику в нужную среду и дает возможность эту логику запускать, сохранять и воспроизводить результаты ее работы. Два больших независимых и определяющих все слоя

Из этого правила следует, что код выполняющий побочные эффекты нужно располагать как можно выше по стеку вызовов. Идеальная цепочка: прочитали => вычислили => записали. Вычисление ничего не должно знать про окружающую среду.

Другой важный принцип проектирования функций Command-Query Separation (CQS). Он не совсем про слои, но очень в тему. Обычно звучит так: "задавая вопрос, не изменяй ответ". То есть геттеры не должны менять состояние, это противоречит их сути и может ломать детерминированность

Ссылки: Телеграм | Youtube | Подкаст
👍10320🔥13👀2🌭1