Саша Беспоясов

Саша Беспоясов

Темы
Неделя
Apr 26, 2021 → May 2, 2021

Архив недели @bespoyasov

Понедельник


Привет! На этой неделе у микрофона Саша @bespoyasov. Работаю в DRIVE2. Пришёл туда как фронтендер, потом писал бекенд, а сейчас занимаюсь R&D проектами с анализом текста и компьютерным зрением 😃

В основном пишу на TS, иногда на Python и C#. В разное время писал на PHP и C++, не зашло ни то, ни то 😃 Пробовал Lisp, но продуктового опыта на нём нет. Веду блог: bespoyasov.ru, топлю за TDD, люблю React. Написал (и переписал) Тяжеловато fuckgrechka.ru/tzlvt

На эту неделю хочу предложить вам вот такой план: В понедельник поговорим об архитектуре. День начнём с наброса — а нужна ли вообще «Чистая архитектура» 😃 Обсудим, что это такое, какие плюсы она даёт, какие у неё издержки, применимо ли это всё ко фронтенду.

Во вторник набросим ещё больше и обсудим ООП и современный фронт. Кто они: «хорошие друзья» или «заклятые враги»? Мертво ли ООП, устарело ли морально, почему его хейтят.

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

В четверг поговорим о том, где и как набраться опыта в разработке. Что эффективнее: университет, галеры, опен-сорс, книги? Как осилить родмап разработчика?

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

В субботу обсудим, кто и как относится к пет-проектам. Не стали ли они завышенным требованием от разработчиков. (Ага, именно в субботу, да 😃)

🔥Тред (@bespoyasov)
@jsunderhood Говоришшш, реакт любишшш... pic.twitter.com/WiyGgRtICi
jQuery я тоже люблю! 😃 Один из любимых хуков вот! 😅 github.com/latviancoder/u… twitter.com/skv_nskv/statu…

@jsunderhood Я вот думаю так. Чистая архитектура, код – строгие правила. Они помогают тем, кто не ориентируется, делать неплохо не думая Поэтому новичкам лично я рекомендую читать книги типа "Чистый код". А для опытных пользователей ПК главное правило – делай нормально и будет нормально
Второй абзац — это то, к чему я постараюсь подвести в конце, но предпосылки (первый абзац) у меня немного другие 🙂 twitter.com/Andre_487/stat…

Как и обещал, начнём с наброса 😃 Что такое чистая архитектура, зачем нужна, плюсы, издержки. Если вы работали c ytq, расскажите о своём опыте? Что было круто, что было неудобно? Будем разбираться, действительно ли это полезный инструмент, или просто переусложнённый хайп.

Начнём с того, что такое «Чистая архитектура». Behold!
notion image

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

Адаптеры и порты — это связь со внешним миром: БД, UI, вот это всё. Если хочется узнать побольше, то вот пара ссылок: - herbertograca.com/2017/11/16/exp… - habr.com/ru/post/269589/ - bespoyasov.ru/blog/clean-arc… Особенно советую — первую. Просто офигенная статья!

Когда я начал постить в блоге (о фронтенде) конспекты книг и статьи об архитектуре, мне стали прилетать вопросы типа «А кому и нафига это вообще надо?».

Я отчасти понимаю природу этих вопросов. Кажется, что архитектура это что-то далёкое от фронтенда: мы же просто формочки шлёпаем да кнопочки двигаем. А все эти Мартины и Физерсы как-то уж очень сильно переусложняют.

Вот нафига мне выделять «слои» в приложении, если всё моё приложение — это небольшое PWA с парой кнопочек? Есть аргументы вида «будет проще переехать с React на что-то ещё» — но я не собираюсь переезжать с React, зачем мне тогда адаптеры для него?

Да чтобы просто нарисовать схему приложения по такой архитектуре у меня времени уйдёт больше, чем на то, чтобы написать его 😃 В чём профит?

Я предлагаю начать с того, что архитектура — это прежде всего инструмент. У любого инструмента есть область применения и ограничения.

@jsunderhood Реквестирую тред про интервью по системному дизайну и архитектуре. У меня завтра собеседование, а инфы по фронтенду кот наплакал 🌚
О! Я сам на таких интервью не бывал, но подозреваю, какие могут быть вопросы 🙂 Предлагаю вернуться к этому в середине дня, а пока оставлю здесь ссылку на статью по теме, которую недавно писал: - bespoyasov.ru/blog/generatin… twitter.com/lizuschiykotik…

@jsunderhood >... максимально независим... От чего?
Если коротко, ото всего, кроме языка, на котором пишем. То есть, домен не должен ссылаться на фреймворки, на UI, на хранение данных. twitter.com/skv_nskv/statu…

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

А в адаптерах и портах — всё, специфичное для конкретной платформы.

Я, пожалуй, не стану покупать шуруповёрт, чтобы вкрутить один саморез. Но если саморезов 1000, то я уже подумаю: потратить 5 тысяч на шуруповёрт или лечить в будущем артрит кисти за бóльшие деньги 😃

Архитектура, как и шуруповёрт, стоит ресурсов. Поддержка сложного проекта с лапше-кодом, как и артрит, — тоже стоит ресурсов, и тоже, как правило, больше.

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

Дело было так: я однажды попал в сложный проект на PHP с кучей легаси и запутанным кодом. Ни о какой архитектуре там речи, разумеется, не шло. Ребята зафигачили стартап, он полетел, побежали фичи и баги, а потом пришёл я 😃

Тогда я только-только начинал знакомиться с хорошими практиками в разработке софта, книжки там читать начал, всё такое. Но уже тогда было понятно, что ясного понимания, как работает система — нет, причём ни у кого 😃

Работать было невозможно, потому что добавишь чё-нибудь-куда-нибудь, где-нибудь-что-то-ещё отвалится. — Так написали бы тестов, чё. Ага, мы тоже так подумали 🙂

Не писались там тесты, как бы мы ни старались 😃 Код был написан так, что чтобы протестировать какой-то модуль, приходилось мокать вообще всё подряд. (Говоря умными словами, код был сильно зацеплен: ru.wikipedia.org/wiki/Зацеплени…)

Поддерживать этот комбайн было трудно. И не только потому, что тестировать было неудобно — было трудно даже понять, что и какой модуль должен делать 😃 Сейчас я бы сказал, что код доменного слоя был размазан ровным слоем (будум-тсс) по всему приложению.

Всё было намешано в кучу. Держать в голове даже один модуль было трудно: модуль мог и за шаблонизацию отвечать, и за преобразование данных. (Умными словами, нарушал SRP: ota-solid.vercel.app/srp)

Как и куда направлены зависимости тоже ясно не было. (Циклические зависимости себя не заставили долго ждать 😅)

Теперь контр-пример: прототип приложения на React. Надо быстро, поддерживать будет, скорее всего, не нужно. А если и нужно — то всё равно переписывать, потому что дизайн будет другой, UX поменяется и т. д.

Страдая от, кхм, ПТСР с прошлого опыта, я накрутил туда архитектуры по всем правилам: вот тебе и домен, вот тебе прикладной слой, адаптеры, всё независимо, найс. Только прототип никому не понадобился, а проект затух 😃

Вместо того, чтобы проверить гипотезу, приложив минимум усилий, я вбухал кучу ресурсов. Ладно хоть писал сам, а то стыдно бы потом было смотреть в глаза команде! 😃

И вот мой первый тогдашний вывод: == Издержки должны быть меньше выгоды == Да, вот так очевидно 😃

После того проекта я решил порефлексировать на него. Что бы произошло, если бы всё-таки прототип пришлось переписать. - Сколько кода я бы мог переиспользовать? - Какой код надо было бы переиспользовать?

*Сейчас пойду поработаю, а после расскажу: - какие выводы получилось сделать после этого, - как я использую ЧА сейчас, - какое минимальное количество усилий стоит прикладывать, - как понять, что пора расширять инструментарий.

Обед! Продолжим 😃 Итак, что бы произошло, если бы всё-таки прототип пришлось переписать. - Сколько кода я бы мог переиспользовать? - Какой код надо было бы переиспользовать?

Кто-то уже мог догадаться, что я клоню к домену. Домен — это самое главное, что есть в приложении. Та функциональность, которая отличает идею одного приложения от другого.

То, что мне точно пришлось бы перенести из прототипа в продукт — именно домен. Да, вероятно, с изменениями, возможно, что-то пришлось бы добавить. Но именно этот код пришлось бы переносить.

Второй вывод: === Стоит начать с домена === Сперва можно и не городить оставшиеся слои, не писать адаптеры к библиотекам, всего этого можно на первом этапе не делать. Но выделить домен — стоит обязательно.

Я это называю, кхм, «прагматичной архитектурой» 😃 Это как правило 20/80, только про дизайн систем. ru.wikipedia.org/wiki/Закон_Пар…

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

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

— Ок, допустим. Но вот я читаю книжки об архитектуре, там сплошное ООП. А я не хочу в свой проект его тащить. Понимаю. Могу обрадовать: архитектура и ООП — вещи ортогональные 😃

Ну то есть понятно, что большая часть книг написана с примерами на ОО-языках, но это не значит, что нам нельзя взять идею и использовать только её. (Почему с ООП проще строить грамотную архитектуру мы поговорим завтра.)

Домен можно вообще писать как хочется. Главное, чтобы код был понятным и независимым. Я, если пишу не в ОО-стиле, то люблю описывать домен в виде типов и чистых функций, которые оперируют данными этих типов: github.com/bespoyasov/www…

Профит в том, что если проект выстрелит и начнёт быстро расти, вам будет проще накрутить мяса вокруг самого важного кода, чем искать этот самый важный код по всей кодовой базе.

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

— Ладно, это всё, конечно, круто, но ты кажется забыл, что мы тут вс же на JS пишем. Какие нафиг типы? 😃 Отсутствие типов тоже не проблема для выделения домена 🙂

Ну то есть да, статичная типизация помогает проектировать, но и без неё можно справиться. Ну там JSDoc, объекты-стабы для тестов, те же классы в конце концов. (Хотя признаю, я начал по-настоящему задумываться о проектировании, когда перелез на TypeScript.)

(Без интерфейсов сложно сконцентрироваться на взаимодействии между сущностями. Труднее выделять публичное API, абстрагироваться от реализаций. У меня есть ощущение, что JS меня как бы подталкивает думать сперва о реализации, а TS — наоборот.)

Я для прототипов тесты, например, не пишу. Но как только становится понятно, что из прототипа надо делать продукт, гораздо проще покрыть тестами уже выделенный код.

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

— Окей, ладно. С доменом разобрались, допустим. Но вот зачем остальные слои? Они нужны? Короткий ответ: не всегда. Длинный ответ ↓ 😃 Когда я думал, что «используя слой адаптеров, проще съехать с React», я отвечал себе, что я и не собирался съезжать с React.

И это правда, перебраться с него на какой-то другой шаблонизатор сложно. У него богатая экосистема, куча уже написанных компонентов. Но что, если я заменю “React” на “Redux” 🙂

Кто-то наверняка задумывался о том, чтобы сменить стейт-менеджер. Кто-то, наверное, даже успешно его менял на какой-нибудь MobX или что-нибудь ещё. Так вот, заменить стейт-менеджер обычно — затратное мероприятие.

Он обычно затрагивает много кода: хранилище, события всякие, привязка к UI. Вместе со всем этим кодом надо и тесты переписывать — а это ещё раза в два больше работы.

@jsunderhood Можно попросить привести более конкретный пример для типового веб приложения? Скажем, для фронт энда онлайн магазина печенек со стандартной функциональностью (список-товар-корзина-чекаут) что будет каким слоем? Сложно смапить на мою ментальную модель пока что
Да! ^_^ Недавно меня уже спрашивали в Твитере, что-куда-и-как можно вынести. Я ответил на примере приложения с котиками 😼 twitter.com/ch_ronik/statu…

Сейчас в дополнение к котикам сделаем онлайн-магазин печенек! 🍪

Допустим, наш магазин продаёт разные виды печенек. У каждой печеньки есть цена, состав и срок изготовления. Пользователи могут покупать печеньки на сайте, указывая предпочтения по вкусам, аллергиям, наличию молока и проч.

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

Дальше, слой адаптеров и портов. (Да, сейчас поговорим о самом внешнем слое, я в конце покажу, почему именно так: будет чуть проще увидеть разницу.) Что у нас тут? - UI: рендер страниц и компонентов, обработка событий; - общение с сервером и API; - сохранение в localStorage...

Задача адаптера — сделать интерфейс стороннего сервиса совместимым с тем, который хочет наше приложение. Это значит, что если API отдаёт данные в виде snake_case, а мы хотим camelCase, заниматься этим будут адаптеры.

Порт — спецификация, как сторонние сервис может общаться с нашим приложением, или как наше приложение хочет, чтобы с ним общались сторонние сервисы.

Это всё был внешний слой. Прикладной слой (между доменом и портами/адаптерами) — описывает сценарии, конкретно этого приложения. Допустим, у нас кроме этого магазина, есть ещё проект, где печеньки просто выставляются в виде произведения искусства (их нельзя купить).

Тогда прикладной слой магазина будет содержать: - работу со списком товаров и корзиной, - сценарии покупки...

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

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

Адаптеры и порты делят внешний мир от нашего приложения как мембрана клетки отделяет её от окружающей среды. И все изменения окружающей среды влияют только на мембрану: появилось что-то, что можно съесть — съели, остальное отсеиваем.

Адаптеры как бы ограничивают распространение изменений. Мы пишем такие «переходники», которые делают внешний мир более удобным для нашего приложения.

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

Это, кстати, ещё и ограничивает распространение ошибок 🙂 Об этом писал Ганмер в «Паттернах отказоустойчивых приложений»: bespoyasov.ru/blog/patterns-… (Офигенная книжка, очень советую.)

Кроме ошибок, это ещё и помогает рефакторить код. Разделение по слоям — идеальный «шов», как называет его Физерс в «Эффективной работе с легаси»: bespoyasov.ru/blog/working-e… (Тоже советую 😃)

Итак, к этому моменту: - Архитектура — это инструмент. У неё есть издержки и выгоды. - В какой мере инструмент использовать — определяет разница между издержками и выгодами. - Не знаете, с чего начать — начните с домена. - Старайтесь привязывать 3-party код адаптерами...

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

Хорошо, вот мы поняли, что нашему проекту на Реакте нужна суровая масштабируемость, и одним выделением доменного слоя мы не обойдёмся. Что делать?

@jsunderhood У нас в компании юзается Mobx, и там просто гигантский стор, в котором и ui данные, и данные сервера. Продуктивно работать тяжело, а переписать это все ещё сложнее
Кстати, да! Забегая вперёд (к рефакторингу и тестируемости): место, где всречаются серверные и клиентские данные — хороший «шов». bespoyasov.ru/blog/working-e… twitter.com/kumma_kirill/s…

@jsunderhood Реквестирую тред про интервью по системному дизайну и архитектуре. У меня завтра собеседование, а инфы по фронтенду кот наплакал 🌚
Теперь немного о собственно проектировании. Допустим, мы знаем, что нашему проекту нужна суровая масштабируемость. Что делать? Первым делом стоит взять ручку, бумажку и пойти «программировать ногами» 😃 twitter.com/lizuschiykotik…

Мы (люди) плохо умеем прогнозировать будущее. Проектирование систем — это прогнозирование будущего. Чем больше исходных данных мы насобираем, тем больше вероятность, что мы правильно составим «карту территории».

(О соотношении карты и территории: ru.wikipedia.org/wiki/Соотношен…)

Что нам необходимо знать? - Какие задачи перед нами стоят. - Какое решение считается удовлетворительным. - Какие есть ограничения.

Чего мы хотим добиться: - Доменный слой должен быть самостоятельным и независимым. - Адаптеры должны подстраивать внешние сервисы под нужды нашего приложения, а не наоборот. - ...

- ...Кода должно быть минимальное необходимое количество. - Модель системы должна быть максимально простой. - Направление зависимостей должно быть к домену.

Я недавно писал пост о дизайне системы с помощью слоёв и DDD: bespoyasov.ru/blog/generatin… Давайте используем его как пример и ответим на вопросы.

Так-с, обед закончился 😅 Ответим на вопросы после работы!

Продолжим 🙂 На какие вопросы мы ищем ответы? В первую очередь — какие перед нами стоят задачи. Потому что ответ на этот вопрос определит, что будет содержать доменный слой.

Кроме этого — какое решение мы посчитаем достаточным, какая требуется глубина проработки. Если мы делаем приложением только под браузер — это одно, а если мы пишем его для браузера, React Native, и Ноды — уже другое.

В первом случае мы можем не прорабатывать слой адаптеров так уж тщательно, потому что переиспользовать какой-то код нам вряд ли потребуется. Во втором случае наоборот.

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

Невозможно проработать систему на 100%. Всегда останется что-нибудь, что можно улучшить. Это стоит иметь в виду, когда мы взвешиваем выгоды и издержки.

При непосредственно дизайне я люблю сперва проектировать домен. Обычно я беру бумажку с ручкой и рисую квадратики со стрелочками 😅 Получается такой UML на минималках.

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

- ...Всё ли нормально с направлением зависимостей; - Следую ли я принципам SOLID; - Что будет, если захочу заменить реализацию какого-то модуля на другую; - Сколько понадобится ресурсов, чтобы поменять платформу, инфраструктуру, whatever.

Обычно получается нечто вроде такой диаграммы (из поста с деревьями):
notion image

Я не стал упарываться, покрывая веб-платформу адаптерами с ног до головы, так как был уверен, что мне это не понадобится. Но зато при проектировании я заметил, что модуль геометрии придётся разбить на 2 отдельных интерфейса. ota-solid.now.sh/isp

Также помогает выделить Driver (управляющие), и Driven (управляемые) адаптеры:
notion image

(На эту тему ещё раз посоветую эту статью herbertograca.com/2017/11/16/exp…)

Диаграмма помогает не писать сразу код, а сперва приметиться на бумаге — «а оно вообще поедет?». Иногда диаграммы помогают обнаружить ошибки проектирования: - функциональность засунули не туда; - модули слишком сильно зацеплены; - ...

- ...Нужна шина событий, чтобы связать какие-то сущности; - Нарушаем SRP, DIP, ISP и прочее. Если паровоз на бумаге поедет, то можно думать в сторону кода.

🔥Тред (@bespoyasov)
Теперь немного о собственно проектировании. Допустим, мы знаем, что нашему проекту нужна суровая масштабируемость. Что делать? Первым делом стоит взять ручку, бумажку и пойти «программировать ногами» 😃 twitter.com/lizuschiykotik…
Писать код ещё рано. Проектиурем! twitter.com/jsunderhood/st…

Да! ^_^ Недавно меня уже спрашивали в Твитере, что-куда-и-как можно вынести. Я ответил на примере приложения с котиками 😼 twitter.com/ch_ronik/statu…
Прорабатываем взаимодействие модулей: twitter.com/jsunderhood/st…

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

Прикладной слой и порты с адаптерами. Я, кстати, видел даже неплохие стартовые шаблоны для того же Реакта: - github.com/eduardomoroni/… - github.com/bailabs/react_…

Держим при написании в голове разницу между выгодами и издержками. Если вы чувствуете, что оверижинирите, опишите в документации описание и не плодите лишний код. Если вы чувствуете, что вот это место, как слишком сильно сцеплено с 3-party кодом — добавляйте адаптеры.

Архитектура — это не только возможность масштабироваться, но ещё и увеличенный порог входа. Возможно, будет нужен онбординг. (Я, например, когда маленьким был, долго не мог вдуплить, что такое DI и как он работает.)

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

@jsunderhood А как ты относишься к идее совы? github.com/feature-sliced
У меня есть смутное подозрение, что это именно то, что в статье “How I put it all together” называют компонентом. (Такой кусок гексагонального пирога.) herbertograca.com/2017/11/16/exp… twitter.com/dskr_dev/statu…
notion image

То есть там конечно есть особенности, и оно не «точь в точь такое же», но кажется, будто бы идея где-то очень близко.

Кстати! Структура папок никак не влияет на архитектуру и не отражает её 😃 То есть мы можем поделить приложение на слайсы/компоненты, которые будут содержать в себе код фичи под каждый случай. Но при этом деплоить, например, по слоям. Вообще без проблем.

А вообще идея разделения файлов/папок на фичи мне больше нравится, чем разделение их на те же «слои». Кажется, что порог входа немного ниже, потому что с первого взгляда на репозиторий видно, какие сущности/фичи есть.

🔥Тред (@bespoyasov)
Теперь немного ссылок на Гитхабы! Есть несколько шаблончиков для Реакта: - github.com/eduardomoroni/… - github.com/bailabs/react_… twitter.com/unetwarm/statu…

Есть и без Реакта! Вот я писал недавно пост об архитектуре, есть репозиторий для с исходниками: - github.com/bespoyasov/tre… А есть и с Реактом, и с Next! Вот сайт недавно переписывал: - github.com/bespoyasov/www

Структура файлов в двух последних репозиториях не отражает слои, но из поведение — вполне. Кстати, репозиторий с сайтом ещё и хорошо показывает, как и когда можно остановить глубину проработки.

Без ссылок на Гитхаб — Тяжеловато: fuckgrechka.ru/tzlvt/ Писал в блоге, почему и как я его переписал. Там даже диаграмма есть! 😃 bespoyasov.ru/blog/tzlvt-upg…
notion image

За диаграмму особо не ругайте, он старая, я тогда ещё не умел рисовать нормально и стрелки в нужные стороны направлять :–/

🔥Тред (@bespoyasov)
И вот мой первый тогдашний вывод: == Издержки должны быть меньше выгоды == Да, вот так очевидно 😃
Плохо умею в треды, продолжение вот тут, простите 😅 twitter.com/jsunderhood/st…

🔥Тред (@bespoyasov)
@_olegkusov Ты правильно заметил, что там в основном отображение. Я дашборда не видел, поэтому сложно советовать, но кажется, что из бизнес-логики там только данные для графиков и таблиц. Рендер данных на экран — как по мне, слой адаптеров, а получение и подготовка — прикладной.
Приложение с котиками тут: twitter.com/bespoyasov/sta…

🔥Тред (@bespoyasov)
@jsunderhood Так вот такие штуки можно и НУЖНО пихать в домен или shared kernel. Они позволяют куда эффективней описывать домен и компоновку кусков приложения. (В идеальном мире их можно бы было встроить в сам язык, но у нас тут жс, а не идеальный мир)
Про домен не соглашусь, shared kernel — да, тоже может быть. Главное не переусердствовать! twitter.com/mr_mig_by/stat…

@jsunderhood А можно вообще найти весь тред про архитектуру в виде какой-нибудь статьи? Формат твитов не очень подходит для таких вещей, а инфа полезная, спасибо за неё)
В самую первую очередь советую вот эту статью! herbertograca.com/2017/11/16/exp… twitter.com/aksenovdev/sta…

Потом ещё DDD: ddd.fed.wiki.org/view/welcome-v…

А дальше — книги 😃 Я в блоге делал конспекты - «Чистой архитектуры», - «Эффективной работы с легаси» - и «Паттернов отказоустойчивых приложений»: bespoyasov.ru/tag/books/ Советую эти книги тоже прочесть. (Желательно — в оригинале!)

Спасибо всем, кто отвечал и задавал вопросы сегодня! ^_^ Ухожу спать. Завтра продолжим и подкинем в костёр несколько ООП-дровишек 😃

Вторник


Доброе утро! Сегодня вторник, а значит поговорим об ООП на фронте. Пока я заливаю в себя кофе, давайте проведём опрос. Как вы думаете, ООП и фронтенд:
🤔 26.8% Хорошие друзья 😊
🤔 12.1% Заклятые враги 😈
🤔 61.1% Беру попкорн 🍿

А пока идёт голосование, обсудим, чем ООП плохо и хорошо, а что его не любят и наоборот. Начнём с хейта 😃

Сразу начну с того, что не каждому проекту ООП нужно. Иногда гораздо проще написать пару функций с объектами, и никаких солидов не надо. Об этом подробнее в конце 🙂

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

Я согласен, что иммутабельные структуры данных — это круто и надёжно. Но сам лично не считаю мутации чем-то плохим, если они контролируемы. Когда мутации становятся беспорядочными, всё и правда резко становится сложным и запутанным.

Но беспорядочные мутации — это не проблема ООП, это проблема плохо написанного кода 😃 Запутанный код можно написать и не мутируя структуры, если data-flow непонятный.

Для управления мутациями давно уже придумали много способов работы, тот же CQS: - bespoyasov.ru/blog/commands-… - en.wikipedia.org/wiki/Command–q… Command-query separation — подразумевает разделение кода на «запросы» и «команды». Запросы возвращают данные, а команды меняют состояние.

С ним, кстати, вполне реально выстроить как 1-way, так и 2-ways data-flow, он достаточно универсален, чтобы быть удобным в обоих случаях.

Так вот, тот ООП энтерпрайз, который следовал CQS, был вполне себе понятным ¯_(ツ)_/¯ Так что, возможно, дело не в мутациях. Ну ок, что есть ещё? А! Куча лишних сущностей! Обмажутся своим ООП и начинают городить фабрики фабрик провайдеров фабрик провайдеров.

Но опять, это не проблема самого ООП 😃 Да, среди принципов SOLID есть SRP, single responsibility principle. Он говорит, что надо делить обязательства между модулями. ota-solid.now.sh/srp Но я видел фабрики фабрик не только в ООП коде.

Может, дело просто в самой его сложности? Ну… ООП сложный, но не сложнее настоящей™ функциональщины. Теорию групп я так и не могу сказать, что осилил 😃 github.com/fantasyland/fa…

Хотя я даже работал на проекте, где это использовалось. Очень оказалось полезно как раз для ООП. Проще стало понимать ковариантность и контравариантность типов. - ru.wikipedia.org/wiki/Ковариант…

Мне кажется, весь хейт в том, что ООП на фронте с JS просто не удобен. Использовать его по-настоящему не получается из-за JS. У него многого не хватает, банально — нет интерфейсов.

Но есть TypeScript 🙂 Он всё ещё страдает от JS-райнтайма, но у него уже достаточное API, чтобы писать нормальный™ код. Мне вот сильно не хватало нормального DI (без декораторов!), пока я не наткнулся на: - github.com/wessberg/di

Другое дело, что это опять-таки не всем проектам нужно 🙂

Парадигма программирования, как и архитектура, — это инструмент для укрощения сложности. И, как с архитектурой, нам стоит исследовать выгоды и издержки перед применением.

Взять те же принципы SOLID. ota-solid.now.sh Мы можем (хоть с оговоркой и не все) использовать их в отрыве от ООП, как инструмент проектирования. Я так Тяжеловато переписал:
bespoyasov.ru/blog/tzlvt-upg…

В коде Тяжеловато даже классов нет 😃 Я вообще считаю, что ООП — это больше не про классы, а про отношения между сущностями. Но классы — это всё ещё наиболее удобный инструмент для написания трушного™ ООП.

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

Я причём не говорю, что интерфейсы и реализации — это строго лишь ООП, нет. Просто как их использовать для проектирования и написания кода, описано обширнее всего в книгах, так или иначе связанных с ООП.

— Ладно, вот простой вопрос: можно ли вообще писать в ООП-стиле фронтовый код? Не бекенд, а фронт? Да. (Но нужен TypeScript 😃)

Есть ошибочное мнение, что фронт — типа ненастоящее программирование. Но современный фронт сложный ¯_(ツ)/¯ А сложное надо проектировать ¯_(ツ)/¯ Кому-то это может не нравиться, кто-то хочет, чтобы вся сложность снова ушла на сервера, но сейчас мы имеем что имеем.

Со сложностью надо как-то справляться. У нас есть фреймворки и библиотеки, это хорошая помощь, но они решают только часть проблем. Проектированием системы всё равно надо заниматься нам самим.

И вот тут ООП может помочь: - Как разделить обязанности между модулями, - как использовать композицию, - что должно быть полиморфным, - где и какие ставить предусловия, - что от чего должно зависеть.

Из всего, что я пробовал у ООП наиболее богатый инструментарий и словарь для проектирования систем ¯_(ツ)_/¯ Круто, если есть или будет что-то ещё более удобное, но я не видел.

Кстати, ООП не запрещает использовать преимущества ФП! 🙂 Мы можем продолжать использовать чистые функции, иммутабельные структуры и вот это всё, даже пиша в ООП-стиле. (Такое слово есть, я проверил 😃)

У Марка Симанна есть отличная статья на эту тему, очень советую: blog.ploeh.dk/2020/03/02/imp…
notion image

Мне в целом воинствующее разделение на ООП / ФП не нравится. Для меня срачи на тему парадигмы выглядят вот так 😅
notion image

Но я немного отступил от темы. Можно ли писать нормальный ООП-код на фронте? Я недавно написал пост о том, как совместить принципы чистой архитектуры, ООП, DDD и всё такое прочее: bespoyasov.ru/blog/generatin…

Внутри ссылаюсь на офигенную статью @hgracaherbertograca.com/2017/11/16/exp… там настолько круто всё разжёвано! Я перечитываю её разок в месяц-два, чтобы рефрешнуть в памяти, как нормально проектировать.

Для Реакта вон люди тоже придумали стартовые шаблоны: - github.com/eduardomoroni/… - github.com/bailabs/react_…

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

Обычно всё начинается с домена, внутри которого лежит пара функций да типы. Применяю S, O, I, а L и D на полшишечки. Чем сложнее становится управлять, тем больше инструментов буду использовать.

Как и обещал, начнём с наброса 😃 Что такое чистая архитектура, зачем нужна, плюсы, издержки. Если вы работали c ytq, расскажите о своём опыте? Что было круто, что было неудобно? Будем разбираться, действительно ли это полезный инструмент, или просто переусложнённый хайп.
Именно поэтому мы вчера столько времени уделяли проектированию: twitter.com/jsunderhood/st… Мы не хотим засорять код с самого начала, но мы хотим быть в состоянии добавить и расширить функциональность и инструментарий при необходимости.

(В Тяжеловато, например, я так и сделал: у меня есть пространство для манёвра с новыми инструментами, но самих инструментов пока нет — они не нужны. fuckgrechka.ru/tzlvt/)

Отследить, в какой момент пора наращивать инструментарий мне помогает ощущение «Чё-та сложна». Иду по индукции с малого, если становится сложно (или там много писать, или повторяться приходится), добавляю инструменты.

Мне ещё иногда кажется, проблема и преимущество JS в том, что «нам не объяснили, как на нём писать правильно». Поэтому, думаю, и выбор парадигмы — больше вопрос удобства, привычки и вкуса.

Так-с, ухожу работать! Потом продолжим 🙂

Продолжим 🙂 Чем ООП полезен? Мне очень нравится, как ООП помогает делать мой код масштабируемым и тестируемым.

Под масштабирумеостью я понимаю возможность дописать, переписать, удалить какой-то модуль без необходимости переписывать соседние модули. Под тестируемостью — возможность удобно подменить зависимость при тесте на стаб или мок.

Пример. Я как-то писал пост о DI: bespoyasov.ru/blog/di-ts-in-… В нём был логгер. Давайте рассмотрим, как он устроен.

В типах я описываю публичный интерфейс: github.com/bespoyasov/di-… Интерфейс — это контракт на поведение, он говорит, как с этим модулем можно общаться, что этот модуль гарантирует предоставить как API:
notion image

Реализация интерфейса описана классом: github.com/bespoyasov/di-… Реализация инкапсулирует в себе детали, которые внешнему миру не важны. Всем потребителям публичного API по барабану, куда уходит сообщение. Им лишь важно, что они могут дёрнуть метод log.
notion image

Обратим внимание, что интерфейс называется более абстрактно, чем реализация. Нам важно сохранять инкапсуляцию и в названии сущности, потому что это снижает зацепление. ru.wikipedia.org/wiki/Зацеплени… Чем меньше разные модули знают об устройстве друг друга — тем лучше.

Затем я в DI-контейнере указываю, какой именно класс реализует интерфейс Logger: github.com/bespoyasov/di-… Таким образом я сбрасываю с себя ответственность за выбор нужной сущности на контейнер — соблюдаю принцип инверсии зависимостей: ota-solid.vercel.app/dip
notion image

В сущности, которой требуется логер, я указываю интерфейс как зависимость: github.com/bespoyasov/di-… То есть мне здесь уже не важно, что реализует Logger. Я просто знаю, что есть некая сущность, которая гарантирует метод log, который я могу тут использовать.
notion image

Это значит, что если я решу заменить консольный логер на какой-то другой, то единственное, что надо будет заменить: реализацию и композицию.
notion image

А чтобы протестировать модуль, который использует этот модуль как зависимость, мне надо замокать интерфейс Logger:
notion image

Этот мок я «подсуну» в регистрацию при тестировании:
notion image

И ничего другого не поменялось!

Если мы ещё не будем забывать о LSP и OCP, то масштабировать будет ещё легче. - ota-solid.vercel.app/ocp - ota-solid.vercel.app/lsp

Теперь поговорим о том, чем ООП неудобен 🙂 Расскажите о своём опыте тоже? пробовали ли? что не понравилось?

DI, за который я сейчас топлю, когда-то был для меня непреодолимым барьером 😃 Я помню, пришёл в проект на первом Ангуляре, а там DI. Вот смотрю в код: вижу, используются какие-то сервисы. А ОТКУДА?! При вызове же ничего такого нет, что за магия?

Поэтому для меня основное неудобство — это в первую очередь порог входа. Перед тем, как затащить какой-то доп. инструмент, я думаю, а это будет поддерживаемым, если я сразу же уйду? Есть кто на подхвате?

@jsunderhood Ну самый очевидный это многословность, интерфейсы, абстрактные классы, дочерние классы, дочерние дочерних, билдер который собирает все эти классы, интерфейс билдера
Ещё, как правильно заметили в комментариях, иногда — избыточная многословность: twitter.com/zavodnoyapl/st… Я видел проект, где чёрт ногу сломит 😃 Писать в ООП-стиле так, чтобы было читаемо — сложно. (Хотя, наверное, в принципе писать так, чтобы было читаемо — сложно.)

Нужно постоянно лавировать между «кучей сущностей» и «дырявыми абстракциями» :–/ У меня есть подозрение, что навык писать понятно приходит только с опытом и насмотренностью.

А проблема с насмотренностью в том, что не весь код, который мы видим каждый день — понятный. Мы начинаем думать, что это норма™, когда это на самом деле не так. Оттуда часто появляется ощущение, что «ООП 💩», «фронтенд 💩», «JS 💩».

Я пока лишь могу порекомендовать читать книжки: bespoyasov.ru/tag/books/ ...и пробовать руками. Ещё хочется порекомендовать читать исходники, но как-то не могу вспомнить, какие бы проекты произвели хорошее впечатление 🤔 Ну разве что Sentry ничего: github.com/getsentry/sent…

Дальше, не очень понятно, как это применять к нынешнему фронтенду — React, Vue, вот это всё. Есть шаблоны: - github.com/eduardomoroni/… Там фреймворки на своём почётном месте во внешнем слое.

Теперь немного о собственно проектировании. Допустим, мы знаем, что нашему проекту нужна суровая масштабируемость. Что делать? Первым делом стоит взять ручку, бумажку и пойти «программировать ногами» 😃 twitter.com/lizuschiykotik…
Это и правда требует больше времени и ресурсов. Но мы помним, что при проектировании мы уже взвешивали издержки и выгоды: twitter.com/jsunderhood/st…

Сейчас уйду ещё поработать, а потом обсудим, почему строить грамотную архитектуру проще, но не обязательно с ООП.

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

Полиморфизм тоже абстрагирует от деталей, позволяя использовать один механизм для работы с разными сущностями. medium.com/devschacht/pol… Композиция (нет, не наследование!) учит выделять функциональность так, чтобы потом её было удобнее сочетать. en.wikipedia.org/wiki/Compositi…

В принципах SOLID также заложено разделение сложного на части, а ещё — барьеры на распространение изменений: ota-solid.vercel.app

Например, SRP и ISP требуют, чтобы модуль занимался только одной задачей. OCP и LSP ограничивает изменения «коробочкой» модуля, а ещё заранее заставляют думать о том, как код будет меняться.

LSP и DIP обращают внимание на зависимости модулей и их направление. Всё это — какие-то части проектирования. У ООП и проектирования похожи терминология и инструментарий, поэтому, мне кажется, принципы проще применять во время рисования квадратиков на бумажке.

А теперь — о том, почему наследование как концепт должно умереть 😃

Наследование классов — это прямой путь к антипаттерну God-Object. Проблема наследования в том, что будущее нельзя предсказать, и мы не можем заранее спроектировать такую иерархию, которая бы отвечала всем требования.

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

Допустим, мы пишем приложение, в котором описываем живые организмы. Что нам нужно, чтобы описать человека, используя композицию? Надо выстроить иерархию сущностей со своими свойствами: Животные → Млекопитающие → Приматы → Человек.

Что нам нужно, чтобы описать человека, используя композицию интерфейсов? Собрать те свойства и методы, которые нам потребуются: Человек = Скелет + Нервная система + Имунная система + Сердечно-сосудистая система + ...

Ну окей, пока выглядит одинаково. ...До тех пор пока не приходит задача научить человека летать. Пусть в нашем приложении появляется Супермен. Он умеет стрелять лазерами из глаз и летать. Как это впихнуть в иерархию сущностей? 😃

Животные → Летающие животные? Летающие приматы? Суперчеловек? Человек. Нипанятна. Нам в какой-то момент придётся создать такой объект, который умеет всё, знает всё, делает слишком много. en.wikipedia.org/wiki/God_object

В композиции мы добавим дополнительные интерфейсы: Супергерой = <...Интерфейсы человека> + LaserShooter + Flyable.

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

Как защититься от наследования? 😅 - Забыть о слове extends (или что там в вашем языке используется 🙂) - Если есть возможность, использовать sealed-классы. docs.microsoft.com/en-us/dotnet/c…

Кстати, а накидайте, пожалуйста, случаев, когда без наследования никак не обойтись? Я что-то пытался сейчас вспомнить, не могу найти подобных. (Абстрактные классы и трейты не считаются! 😃)

🔥Тред (@bespoyasov)
@jsunderhood На ум приходит только когда надо переопределить метод в вендорах (понимаю надо форк или делать что то аля прокси, но мы ж ленивые)), наследуешь класс вендора, переопредеяешь нужный тебе метод, подсовываешь свой новый класс в di заместо вендоровского и делаешь вид что все норм:)
Да, я совсем забыл, что мы живём в реальном мире 😃 twitter.com/zavodnoyapl/st…

Доброе утро! Сегодня вторник, а значит поговорим об ООП на фронте. Пока я заливаю в себя кофе, давайте проведём опрос. Как вы думаете, ООП и фронтенд:
В сегодняшнем треде об ООП: twitter.com/jsunderhood/st… ...мы уже немного затронули тестируемость :–) Завтра поговорим о тестах подробнее: - Обсудим, как делать код читаемым и тестируемым. - Поболтаем за TDD и посмотрим на него в деле.

Поговорим, как упростить тесты и найти на них время, обсудим причём тут TDD и парное программирование. А, да! И ещё подведём итоги утреннего голосования конечно же 😃

@jsunderhood - Изменение поведения/композиции стороннего объекта. - Когда высокие требования по производительности и потреблению памяти, один объект предпочтительнее пяти. - Создание мока, изолированного от внешнего мира, для контекста тестирования.
Первый пункт сегодня упоминали, второй — прям хорошо. (Не уверен, что актуально для фронта, но забывать об этом всё равно не стоит, да.) twitter.com/jin_nin/stat…

Среда


По результатам вчерашнего голосования фронтенд и ООП скорее хорошие друзья, чем заклятые враги, но большинство предпочитает попкорн ^_^
notion image

А сегодня поговорим о том, как сделать код читаемым и тестируемым ^_^ Расскажите о своих приёмах, как вы улучшаете кодовую базу на проектах? Какие применяете методы, принципы, эвристики? Я пока начну 🧶

Самое простое (и одновременно сложное 😃) — это нейминг. Хорошие и внятные имена для переменных и функций — это очень мощный инструмент. (Первая книга на тему, которую я прочёл — это «Читаемый код» Фаучера: bespoyasov.ru/blog/the-art-o… )

Хорошее имя для сущности: короткое, но полное и описательное. На Гитхабе есть классный чеклист по неймингу сущностей: github.com/kettanaito/nam…

Я люблю проверять имена всех экспортируемых сущностей на понятность со стороны пользователя. «Если я буду импортировать эту функцию из модуля, я пойму, что она делает? какова область её ответственности? как её использовать?»

Например, внутри модуля пользователя функция create выглядит органично, не дублирует контекст, короткая, описывает действие:
notion image

Но если функцию импортировать и начать использовать, то уже не так очевидно:
notion image

А вот тут — наоборот:
notion image

Годный шаблон для названий можно вот тут посмотреть: github.com/kettanaito/nam…

@jsunderhood А что на счет бэма? Еще актуально?
Знаю проект, где всё ещё используется облегчённая версия БЭМ. Хотя в личных проектах я всё чаще CSS-модули использую ¯_(ツ)_/¯ twitter.com/yourfckingdrea…

Шаблон A/HC/LC: prefix? + action (A) + high context (HC) + low context? (LC) В идеале по названию переменной должно быть понятно, функция это, булево значение или что-то ещё.
notion image

Для булевых значений можно использовать префиксы: should, is, has, will, did. Для функций — первым словом лучше поставить глагол действия: get, set, update, remove, delete, push…

Иногда (редко) от шаблона можно отойти, если двусмысленность получается исключить: let mounted = false — тут сложно подумать, что mounted что-то кроме boolean.

Если прям совсем коротко, то в коде должно быть ровно столько информации, сколько необходимо для правильного его понимания. Там не должно быть лишнего: - мусор шумит и отвлекает от смысла; - запутанные выражения требуют большей когнитивной нагрузки при чтении. twitter.com/unetwarm/statu…

Много о том, как делать так, чтобы было удобно читать: - добавлять ранний return, чтобы раньше избавляться от условий, чтобы не держать их в голове; - явно выносить смысл сущности в название, чтобы избегать двусмысленности. Это как «Пиши. Сокращай», только для программистов 😅

Живёт и здравствует! 😅 Он чем-то на jQuery похож: мы сейчас им можем не пользоваться, но этот инструмент настолько сильно повлиял в своё время, что просто так он уже не исчезнет 🙂 twitter.com/unetwarm/statu…

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

Моё любимое — не используйте аббревиатуры, пожалуйста 😃 twitter.com/crocodoyle/sta… (А если используете, обязательно документируйте.)

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

Используйте паттерны проектирования. Есть замечательная подборка паттернов на том же Гитхабе, очень советую посмотреть: github.com/kamranahmedse/…

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

Паттерны удобно использовать в связке с SOLID. Некоторые из принципов прямо подразумевают какой-то из паттернов. Мы с twitter.com/dex_157 в нашей книжке о принципах SOLID добавляли разделы с паттернами под каждый принцип. ota-solid.vercel.app

Чаще рефакторите код, но без фанатизма ¯_(ツ)_/¯

Писать код и рефакторить — это как «писать» и «редактировать статью», сложно делать одновременно. Если кусок кода попался большой, стоит дать ему «отлежаться». Когда вы начнёте работать с ним на свежую голову, то будет гораздо проще начать думать о коде с точки зрения читателя.

А ещё (самое сложное для меня) надо купировать перфекционизм 😅 Отрефакторить до идеала сложно, а чаще всего не нужно. Пользуемся правилом 20/80 — 20% усилий должны приносить 80% результата. ru.wikipedia.org/wiki/Закон_Пар…

Чтобы рефакторить безопасно, пишите тесты. Физерс в «Эффективной работе с легаси» писал о том, как можно рефакторить старый неповоротливый комбайн: bespoyasov.ru/blog/working-e…

Он предлагает искать швы — места, в которых можно относительно безопасно «распилить» комбайн на части. Покрыть швы тестами, а уже потом начинать рефакторинг. Я пробовал, это и правда работает.

Как найти хороший шов? Обычно шов — это место, где мы можем заменить одно поведение другим: месте соединения модулей. В хорошо написанном коде такие места выделены явно, потому что модули слабо зацеплены.

Представьте, где именно вы бы разделили систему на несколько частей (по смыслу, по поведению, по зависимостям) — там и будет шов.

В книжке много техник, как работать с кодом, когда вы уже определились со швом. Типа, как заменить зависимость: - одну зависимость за раз; - определить, какую зависимость хотим поменять; - покрыть шов тестами; - вынести текущий код в отдельный класс; - заменить класс на другой.

Раз уж мы о книгах заговорили, то ещё «Чистый код» Мартина могу посоветовать: bespoyasov.ru/blog/clean-cod… Хотя и считаю, что «Эффективная работа с легаси» шире, глубже и практичнее ¯_(ツ)_/¯ bespoyasov.ru/blog/working-e…

Ещё офигенная и практичная книга — “Debug it!” («Отдебажь это!», простите за кустарный перевод): bespoyasov.ru/blog/debug-it/ Она вся состоит из рецептов, как работать с багами из-за непонятного кода.

Там даже содержание — это уже рецепт! 😃 Глава 1 — Исследовать обстановку Глава 2 — Воспроизвести проблему 3 — Определить причину 4 — Исправить 5 — Как не допустить такой ошибки в будущем ...и т. д.

Внутри каждой главы есть списки действий под ситуацию. Короче, рекомендую.

От читаемости к тестированию! 🦸 Используйте TDD 🙂

TDD мне экономит кучу времени. К нему надо привыкнуть, потому что сперва приходится «вывернуть мозги», но он быстро окупается.

С ним: - Исчезает проблема «дополнительной работы» - Писать тесты и рефакторить входит в привычку - Рефакторить безопаснее - Видно сущности, делающие слишком много - API проектируется до реализации, и-за чего становится удобнее

Я недавно делал доклад о TDD на Frontend-crew: - youtube.com/watch?v=1SGb-l… - bespoyasov.ru/talks/podlodka… Там рассказываю об этом подробнее: - как внедрить на проекте; - как использовать; - как сделать тесты проще.

Как упростить тесты при работе по TDD: - Чаще использовать чистые функции - Обращать внимание на зацепление кода - Тестировать только свой код - Использовать удобные инструменты - Потратить время на удобную инфраструктуру

С TDD можно искать пахнущий код. Код пахнет, если: - Тестов слишком много по сравнению с другими модулями - Описание ссылается на несвязанные вещи - Ожидание от теста оформлено невнятно - Подготовка теста слишком сложная - Тест проверяет детали реализации - Тест всегда зелёный

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

Я ещё когда-то написал книжку с примером разработки крестиков-ноликов: bespoyasov.ru/ttt-tdd/ Там показываю, как переходить по циклу TDD, в какой момент приступать к рефакторингу, на что обращать внимание.

TDD можно использовать и при работе с React тоже. Недавно я проводил воркшоп об использовании TDD при разработке React-приложений: bespoyasov.ru/talks/?full#1 Он длинный, около 5 часов, но там я прохожусь по всем основным концепциям, а именно, как тестировать:

- ...Функций бизнес-логики. - Функции, возвращающие случайные значения. - Простые компоненты. - Кастомные хуки, их связь с компонентами. - Работу со стором. - Асинхронные функции и вызовы API. - Пользовательские действия: клик, клавиатура.

Так-с, пора работать! Продолжим во время обеда 😃

@jsunderhood Основное правило для меня (для читаемости и понимаемости) — не заставлять мозг скакать вверх-вниз по уровням абстракций в рамках одной функции. Например избегать в одной функции проверки "есть ли пользователь в группе админов (уровень БЛ)" и "есть ли файл на диске (уровень IO)"
Наглядный пример соблюдения SRP и места, где можно провести шов по зависимостям, если вдруг вы обнаружите у себя такое место ^_^ twitter.com/skyh/status/13…

Продолжим! Чем же так хорош TDD для тестируемости и читаемости? Он сразу поставит нас в ситуацию, когда сперва придётся думать о тестируемости. Писать код, который будет неудобно тестировать, по TDD — очень сложно 😃

Напомню стандартный цикл разработки по TDD. В нём 3 этапа: - красная зона — на ней мы пишем тест, проверяем, что он падает по нужной причине; - зелёная — пишем реализацию, которая тест проходит; - синяя — рефакторим код и тесты.
notion image

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

Чем больше приходится готовить зависимостей, тем выше вероятность, что модуль делает слишком много — а это нарушение SRP и запах кода.

Когда мы проверяем, с какой причиной падает тест, он становится таким, которому можно доверять. (Если мы видим, что тест красный, когда ожидание не выполняется, и зелёный, когда выполняется — это доказательство работы правильной теста.)

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

А ещё TDD — это единственный способ безопасно (или даже вообще хоть как-то) отрефакторить легаси 😃

Кроме TDD тестируемость улучшит Dependency Injection. Вместо того, чтобы мокать всё подряд, можно использовать DI, и подмешивать во время тестов нужные зависимости.

DI — это не обязательно контейнеры и всё такое страшное, можно использовать кустарный DI через объект с зависимостями в конце. Об этом я тоже недавно писал пост: bespoyasov.ru/blog/di-ts-in-…

Автоматизация рутинной работы — тоже полезная штука, особенно в том, что касается форматирования и выделения ошибок/практик-признанных-плохими. twitter.com/unetwarm/statu…

Сообщения о комитах — тоже часть кодовой базы. Мне на больших проектах нравится использовать conventional commits — они хорошо управляют фокусом внимания при чтении: conventionalcommits.org/en/v1.0.0/

@jsunderhood Из простого — удаляю старый код и убираю дубликаты.
Копипаста, кстати, не всегда однозначное зло: bespoyasov.ru/blog/copy-past… twitter.com/myjsalterego/s…

Дублирование кода на ранних этапах может показать, как всё на самом деле работает, и какие паттерны мы ещё не увидели. Удаление дублирования — это прогнозирование будущего. Чем больше исходных данных удастся собрать, тем точнее будет прогноз.

Чтобы не потерять места с копипастой, помечаю их коммент-флагом DUPLICATE. После самого флага пишу, какую функциональность он дублирует. Это даёт флагу осмысленное и уникальное имя, по которому потом проще искать места для рефакторинга.

Оно немного противоречит DRY: ru.wikipedia.org/wiki/Don’t_repeat_yourself ...но экономит время в будущем. Проще вынести действительно общую функциональность потом, чем управлять деталями почти одинаковых реализаций.

@jsunderhood А можешь рассказать, как это должно работать? Я поняла концепт TDD, когда работаешь с нуля, а вот как с ним быть, когда у тебя оттакенный кусок запутанного старья, которое надо привести в приличный вид?
Да ^_^ Если приходится писать тесты для махрового легаси, которое писали до вас, то советую посмотреть на книжку Физерса «Эффективная работа с легаси»: bespoyasov.ru/blog/working-e… Чуть подробнее сегодня писал вот тут: twitter.com/jsunderhood/st… twitter.com/nat_davydova/s…

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

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

В книжке много техник, как работать с кодом, когда вы уже определились со швом. Типа, как заменить зависимость: - одну зависимость за раз; - определить, какую зависимость хотим поменять; - покрыть шов тестами; - вынести текущий код в отдельный класс; - заменить класс на другой.

🔥Тред (@bespoyasov)
@jsunderhood Dry вообще переоценён
Как и со всеми инструментами, перед применением стоит сравнить выгоды и издержки в каждой конкретной ситуации ^_^ twitter.com/makhov/status/…

Кстати, какие вы используете настройки для ESLint? 😃

Ещё, кстати, в TypeScript я стараюсь описывать тип-аргументы в дженериках не одной буквой, а нормальными названиями, когда это имеет смысл 😅 Мне нравится руководство по тип-аргументам в C#: docs.microsoft.com/en-us/dotnet/c… (Если в проекте не принято иначе, конечно.)

А вот старый код — действительно зло. Он отвлекает, а иногда и вводит в заблуждение. Если я подозреваю, что код мне понадобится в будущем, я стараюсь удалять его атомарно: в рамках пул-реквеста или комита.

Тогда я смогу найти удалённое по истории и восстановить. Это потребует каких-то ресурсов, но зато код будет чище и прямолинейнее. Пусть напрягается гит, короче.

То же могу сказать и про закомментированный код. Он как бы удалён, но как бы нет. А когда и как его использовать — обычно никто не знает 😅 Лучше распрощаться с ним.

🔥Тред (@bespoyasov)
Я люблю проверять имена всех экспортируемых сущностей на понятность со стороны пользователя. «Если я буду импортировать эту функцию из модуля, я пойму, что она делает? какова область её ответственности? как её использовать?»
Часть треда снова ускакала не туда, простите :–/ twitter.com/jsunderhood/st…

@jsunderhood Documentation first! Но если более приземленно, то я выработал привычку перед написанием класса, метода или функции описывать javadoc. И это отлично работает: ты описал что функция должна получить, что дожна вернуть, и тут х.як вылазит массив вместо объекта…
Тоже описываю API до начала реализации. Помогает раньше найти ошибки на предыдущем этапе проектирования, если они были. С TS — вообще благодать: он сразу красным подсветит несовместимые типы. twitter.com/AntonShevchuk/…

Дальше, чтобы код был понятнее, его должно быть как можно меньше 😃 Всё, что можно может сделать браузер, лучше отдать ему — он сделает это лучше, оптимальнее и быстрее.

Нужно сериализовать форму? Используем FormData: developer.mozilla.org/en-US/docs/Web… Там есть конечно трудности со всякими кастомными контролами, но процентов 80 случаев можно покрыть только ей.

Нужно сделать ленивую загрузку картинок? Испольуем loading="lazy": developer.mozilla.org/en-US/docs/Web… Опять же, полифилим только для тех, у кого это не работает и только если надо 🙂

Ну вы поняли 😃 Кнопки — кнопками, короче.

Непонятное стороннее API лучше прятать за фасадом, чтобы намерение было выразительнее: github.com/kamranahmedse/…

Если язык позволяет, то для выбора из нескольких вариантов используйте pattern matching: - docs.microsoft.com/en-us/dotnet/c… (Это ещё и безопаснее в некоторых случаях.) Для TS тоже есть реализации! - github.com/nrdlab/pattern…

Снова перерыв на работу 🙂 Вечером продолжим!

@jsunderhood А ещё есть proposal на pattern matching в js, надеюсь, когда-нибудь мы его увидим) github.com/tc39/proposal-…

Продолжим! Ещё один приём, который улучшает читаемость — CQS, command-query separation. - bespoyasov.ru/blog/commands-…

Запрос — функция, которая возвращает результат и не имеет сайд-эффектов. Команда — функция, которая меняет состояние системы и ничего не возвращает.

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

Ещё один приём рефакторинга, который улучшает читаемость — вынесение деталей в метод или функцию: - bespoyasov.ru/blog/missing-a… Это чем-то похоже на фасад, но над своим кодом: - github.com/kamranahmedse/…
notion image
notion image

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

Ещё одна важная часть читаемого кода — это ошибки и стек-трейс. За сообщениями об ошибках тоже надо следить, потому что это такая же часть кодовой базы. - bespoyasov.ru/blog/make-erro…

Чем чище и понятнее ошибки, тем проще дебажить код ¯_(ツ)_/¯

Кстати, вот мы говорили про вынесение кода в функцию или метод. Можно делать это не руками, а встроенными инструментами рефакторинга в IDE. Например, вот для VS Code инструкция: - code.visualstudio.com/docs/editor/re…

Ну и конечно — документация! В ней нам стоит описывать не «как оно работает», а «почему оно работает именно так». Ответ на вопрос «почему?» — это важный кусок контекста задачи, который может потеряться. Лучше его зафиксировать в документации.

А на вопрос «как оно работает», считаю, должны отвечать тесты 🙂

Давайте теперь поговорим о том, когда можно продать часть читаемости взамен на производительность 😃 - Были ли у вас такие случаи? - Что это было: алгоритм, чудачество API? - В какой момент вы в принципе можете себе такое позволить?

У меня за всё время работы таких случаев не было вообще. Обычно мне хватает оптимизаций при сборке. Но вдруг и с JS бывает такое, что приходится колдовать?

Случаи из не-JS мира тоже приветствуются! 😃

Как и обещал, начнём с наброса 😃 Что такое чистая архитектура, зачем нужна, плюсы, издержки. Если вы работали c ytq, расскажите о своём опыте? Что было круто, что было неудобно? Будем разбираться, действительно ли это полезный инструмент, или просто переусложнённый хайп.
Что происходило на неделе / Понедельник: Архитектура, проектирование, зачем это всё, как подружить DDD и чистую архитектуру с фронтендом twitter.com/jsunderhood/st…

Да! ^_^ Недавно меня уже спрашивали в Твитере, что-куда-и-как можно вынести. Я ответил на примере приложения с котиками 😼 twitter.com/ch_ronik/statu…
Спроектировали магазин печенек по всем канонам ЧА и DDD: twitter.com/jsunderhood/st…

Теперь немного о собственно проектировании. Допустим, мы знаем, что нашему проекту нужна суровая масштабируемость. Что делать? Первым делом стоит взять ручку, бумажку и пойти «программировать ногами» 😃 twitter.com/lizuschiykotik…
Обсудили практические аспекты проектирования: twitter.com/jsunderhood/st…

Писать код ещё рано. Проектиурем! twitter.com/jsunderhood/st…
Подвели итоги: twitter.com/jsunderhood/st…

Доброе утро! Сегодня вторник, а значит поговорим об ООП на фронте. Пока я заливаю в себя кофе, давайте проведём опрос. Как вы думаете, ООП и фронтенд:
Вторник: ООП, надо ли его использовать во фронтенде, как это делать, как это делать проще. twitter.com/jsunderhood/st…

Парадигма программирования, как и архитектура, — это инструмент для укрощения сложности. И, как с архитектурой, нам стоит исследовать выгоды и издержки перед применением.
Обсудили, почему проектировать удобнее в терминах ООП, но не обязательно в них: twitter.com/jsunderhood/st…

Продолжим 🙂 Чем ООП полезен? Мне очень нравится, как ООП помогает делать мой код масштабируемым и тестируемым.
Чем ООП полезно: twitter.com/jsunderhood/st…

Теперь поговорим о том, чем ООП неудобен 🙂 Расскажите о своём опыте тоже? пробовали ли? что не понравилось?
Чем ООП неудобно: twitter.com/jsunderhood/st…

А теперь — о том, почему наследование как концепт должно умереть 😃
Composition over inheritance: twitter.com/jsunderhood/st…

А сегодня поговорим о том, как сделать код читаемым и тестируемым ^_^ Расскажите о своих приёмах, как вы улучшаете кодовую базу на проектах? Какие применяете методы, принципы, эвристики? Я пока начну 🧶
Среда: как сделать код читаемым и тестируемым. twitter.com/jsunderhood/st…

Шаблон A/HC/LC: prefix? + action (A) + high context (HC) + low context? (LC) В идеале по названию переменной должно быть понятно, функция это, булево значение или что-то ещё. pic.twitter.com/MsKqMF25WA
Шаблон для нейминга сущностей: twitter.com/jsunderhood/st…

Используйте паттерны проектирования. Есть замечательная подборка паттернов на том же Гитхабе, очень советую посмотреть: github.com/kamranahmedse/…
Паттерны проектирования: twitter.com/jsunderhood/st…

От читаемости к тестированию! 🦸 Используйте TDD 🙂
Как и зачем использовать TDD: twitter.com/jsunderhood/st…

Продолжим! Ещё один приём, который улучшает читаемость — CQS, command-query separation. - bespoyasov.ru/blog/commands-…
Приёмы и эвристики для улучшения читаемости: twitter.com/jsunderhood/st…

Да ^_^ Если приходится писать тесты для махрового легаси, которое писали до вас, то советую посмотреть на книжку Физерса «Эффективная работа с легаси»: bespoyasov.ru/blog/working-e… Чуть подробнее сегодня писал вот тут: twitter.com/jsunderhood/st… twitter.com/nat_davydova/s…
Что делать с махровым легаси: twitter.com/jsunderhood/st…

Копипаста, кстати, не всегда однозначное зло: bespoyasov.ru/blog/copy-past… twitter.com/myjsalterego/s…
Копипаста — не всегда однозначное зло: twitter.com/jsunderhood/st…

Подведём итоги за сегодня 🙂 - Хорошая читаемость снижает когнитивную нагрузку при чтении кода. - Паттерны проектирования, эвристики и рефакторинг помогают улучшить читаемость. - Тесты помогают рефакторить безопасно. - Чтобы рефакторить легаси, удобно использовать швы. - ...

- ...Грамотная архитектура улучшает тестируемость. - TDD также улучшает тестируемость и помогает разбивать легаси на модули. - DI — не обязательно контейнеры, можно проще. - React тормозит на глубоких деревьях 😅

Завтра поговорим о том, как расти в разработке. Обсудим, что лучше: - учиться в университете, - окунуться в боевую разработку, - найти ментора, - читать книги, - участвовать в опен-сорсе.

🔥Тред (@bespoyasov)
@jsunderhood Товарищ ошибается, и usr - это не аббревиатура :-) /usr означает "user", но со временем пользовательские каталоги уехали в /home, а название осталось. Аббревиатуру придумали позже (backronym), а мораль истории - меняйте название если логика кода меняется
Я скорее тут хочу подсветить, сколько недопонимания это имя вызывает 🙂 В ядре Линукса, думаю, хватает ограничений, чтобы называть всё так, как оно названо. Но в JS я стараюсь писать понятнее. Но совет «менять названия, если меняется логика» — отличный! 🔥 twitter.com/kpumuk/status/…

Четверг


Доброе утро четверга! ^_^ Чем ближе конце недели, тем больше мы уходим от хард-скилов 😃 Сегодня поговорим о том, где разработчикам набираться опыта, вообще и эффективнее всего. Опрос! Что из перечисленного оказало на вас сильнейшее влияние?
🤔 10.8% Университет, курсы
🤔 65.9% Боевая разработка
🤔 17.2% Ментор
🤔 6.2% Опен-сорс

На самом деле понятно, что пункты не взаимоисключающие, в жизни их можно сочетать 🙂 Я попробовал всё, кроме, пожалуй, опен-сорса, и мне сейчас кажется, что самый эффективный способ — это «боевая разработка + ментор».

За весь свой опыт я помню 3 случая, когда рост был взрывным — и все 3 случая были на работе под присмотром ментора 😃

Верстать я начал ещё в школе, но там у меня под рукой лишь были курсы Попова и много свободного времени 😃 Показать результаты особо было не кому, проверить их тоже никто не мог.

Я нашёл эти курсы на Ютубе! 😱🙀🤠 youtube.com/watch?v=jj2TXJ…

С программированием было прям совсем худо. Гугл не особо помогал, потому что я ещё не умел нормально гуглить вопросы, которые мне были нужны. Эксперименты часто приводили не к тем результатам, которые были нужны 😅

Первый значительный скачок произошёл году в 2010, на первом большом проекте. Писали на пару с чуваком из, кажется, Австралии: он занимался бэкендом, я фронтом.

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

Я бы не сказал, что он был прям ментором, но на ошибки указывал, хорошие решения подсказывал. Забавно, что всё это происходило на фрилансе ¯_(ツ)_/¯

Второй скачок был в команде, где я написал CRM
bespoyasov.ru/projects/reque… Там познакомился с Реактом, написал первый сервер, потыкал палочкой в Python и Django. Это всё — тоже под присмотром тимлида. Лёха, привет! 😃

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

Третий скачок был в D2. Тут техдир открыл мне дорогу в «настоящее программирование™» 😅 Я пописал на шарпе и .net, лучше понял, что такое грамотная архитектура, познакомился с концепциями, о которых раньше представление имел, но очень смутное.

Ну и сейчас я вот занимаюсь R&D проектами всякого около-ML толка. Учусь реализовывать алгоритмы, которые нахожу в разных научных статьях. При этом я не говорю, что мне не пригодились знания из книг. Пригодились! Просто, чтобы их как-то применять, мало было прочесть 😃

Надо было, чтобы кто-то разжевал что с чем складывать, чтобы оно работало. К некоторым книгам я возвращаюсь время от времени, потому что осознаю, что понял прочитанное совершенно неправильно. (Иногда смотрю в конспект, и если вижу, что понял верно, то книгу не перечитываю.)

Университет, пожалуй, был самым малополезным из всех перечисленных пунктов. Ну то есть, там были попытки привить «инженерный подход» к задачам, а ещё я железки разные потыкал, но больше вещей, которые бы мне были полезны сейчас, я особо не помню.

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

И вот сейчас смотря на это всё я думаю, что «ментор на работе» — это прям самое эффективное сочетание для роста 😃 А что думаете вы?

Доброе утро четверга! ^_^ Чем ближе конце недели, тем больше мы уходим от хард-скилов 😃 Сегодня поговорим о том, где разработчикам набираться опыта, вообще и эффективнее всего. Опрос! Что из перечисленного оказало на вас сильнейшее влияние?
Четверг: как расти разработчикам, как расти эффективнее. twitter.com/jsunderhood/st…

Сейчас я доберусь до завтрака и поговорим о плюсах и минусах каждого из пунктов 🙂

По моему опыту хороший ментор мне нужен не только, когда я был джуном. Проблема в том, что чем выше я уже вырос, тем сложнее найти ментора :–/ twitter.com/unetwarm/statu…

Мне ещё очень нравится вот эта заметка о росте, не могу не поделиться: github.com/bobuk/addmeto.…

Мне сейчас повезло: я попал в команду, откуда можно опыт тоннами выкачивать — чем и занимаюсь 😃

Давайте начнём с университета ¯_(ツ)_/¯ Я понимаю, что не мне с моим дипломом Уфимского технического говорить об университетском образовании, но тем не менее.

Из плюсов я сейчас вижу, пожалуй, нетворкинг. Это именно то, чем я не занимался в университете 😅 Университет — это место, куда попадают люди, с которым можно попробовать что-то вместе сделать. Не с каждым университетом и не с каждым студентом. Но всё же.

Ещё один плюс — могут научить действительно полезным вещам, если попасть в правильный ВУЗ и на правильную специальность. Под правильными я тут понимаю такие, которые совпадают с вашими интересами. Мне повезло наполовину.

Ещё плюс: отсрочка и военная кафедра ¯_(ツ)_/¯ Я при поступлении уже работал, знал, где хочу развиваться и куда расти — тратить год на армию в мои планы не входило. Прошёл военную кафедру, ушёл в запас, мне понравилось 😅

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

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

Одна единственная специальность. В 17 лет мне надо выбрать то, чем я буду заниматься ближайшие 5 лет, а то и всю жизнь, А-ха! 😅 Мне нравится концепция major-minor, но остаётся только слюнки пускать. Денег на зарубежный университет у меня не было. (Да и на Москву тоже.)

Преподаватели, которым не хочется учить / хочется утвердиться. Таких я не помню, чтобы встречал, но слышал рассказы из других ВУЗов. Это какая-то крайняя дичь вообще, тут обсуждать особо даже нечего.

В общем, всё сильно зависит от ВУЗа, но я больше склоняюсь ко мнению, что мне он оказался почти бесполезен. Исключение: военный билет, некоторые предметы типа сетей и администрирования.

Курсы! 😃 Я проходил какие-то курсы на Udemy и где-то ещё. Тут могу сказать, что любые новые знания с курсов надо сразу пробовать включать в работу. Потому что иначе всё быстро забудется, и толку не будет.

В курсах, мне кажется, самое полезное и важное — обратная связь и сообщество. Потому что учиться надо на ошибках, так по крайней мере до меня доходит быстрее, так как есть контр-пример.

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

+: курсов огромное количество. –: а чёрт поймёт, какого они качества 😃 +: можно (хоть и трудно) найти качественную личную программу с персональным наставником. –: это будет дорого 😃 Хотя если пересчитывать, всё равно дешевле ВУЗа, наверное.

Идём к самому интересному 😃 Давайте следующим пунктом выберем боевую разработку.

Несомненный жирнейший плюс — это настоящий рабочий опыт, которым можно светить в резюме. Да, даже если это была галера, это всё ещё опыт.(Мои первые годы после фриланса были на галере.) Соответственно минус — можно попасть на галеру 😃

Новичкам в боевой разработке трудно определить, они в хорошую компанию вот попали или нет? То, как устроены процессы вот тут, — это нормально? Все так делают? А можно уходить спустя 3 месяца? А меня куда-то ещё возьмут? 3 месяца — это же мало, наверное.

Другой плюс боевой разработки: нет романтического флёра IT, который иногда продают курсы. Просто ещё одно ремесло. Изнутри можно посмотреть на «настоящий код™», на компромиссы, как вообще бизнес и разработка связаны, откуда требования берутся и вот это всё.

Минус — это может отпугнуть, если попасть не туда 😞

@jsunderhood Если бы в вузе можно было бы купить изучение одного предмета как курс, было бы топ
Да! Я бы «сети» как раз и купил 😅 twitter.com/Doodidan/statu…

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

А если попасть в хорошую команду, то можно найти людей, у которых перенимать опыт.

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

Особенно отчётливо это было на фрилансе и на галере 😃 Нужно было много работать, чтобы были деньги, но делать приходилось одно и то же. Времени на что-то ещё не оставалось. Как в такую ловушку не попасть, я хз ¯_(ツ)_/¯ Видимо, надо какую-то прокачанную осознанность иметь.

Зато я научился многое автоматизировать. Придумал себе, кхм, «веб-компоненты» 😅 bespoyasov.ru/blog/templates/

Это были такие папки с «компонентами». Каждый компонент состоял из HTML-шаблона, каких-то скелетных стилей и скриптов с логикой. Обычно это были разные элементы типа слайдеров, каруселей, кастомных селектов и прочего.

Я их подключал, конечно, не одним импортом, а тремя (разметка, стили и скрипты), но работали они независимо друг от друга и от контекста 😃

Там же пришлось научиться и «прогрессивному джипегу» в вёрстке: bespoyasov.ru/blog/time/ Типа страница готова в любое время, но проработана на какое-то количество процентов.

А вот work-life баланс найти на фрилансе трудно. Для этого, кажется, нужна культура и команда.

Чуть позже поговорим о менторстве 🙂

@jsunderhood Идеально иметь такое комбо: боевая разработка + ментор в том же контексте (старший коллега, которому не пофиг на эффективность) + коммьюнити людей, заинтересованных в росте. Есть даже компании, где такое применяют!
Да, если ментор где-то «на стороне», много контекста задачи может потеряться при коммуникации. Окружение и команда тоже важно: когда есть, с кем и чем поделиться, делиться приятнее и безопаснее ^_^ twitter.com/mr_mig_by/stat…

@jsunderhood Можно прийти к состоянию, когда работа превращается в профессиональный спорт. А это ещё хуже. Но самое страшное - работодатели это очень любят!

Продолжим! Расскажу, почему я считаю, что ментор нужен, почему не только джунам и почему боевая разработка без менторства растит медленнее.

Ментор, как мне кажется, — это не учитель. Возможно, у меня искажение, но при слове «учитель» я сразу представляю какие-то подчинительско-иерархические отношения. А это совсем не то, что нужно.

Для меня ментор — это как кто-то кто переехал в другую страну до меня, насобирал шишек и теперь может предупредить меня, как именно стоит переезжать.

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

Объясню: очень сложно передать какой-то опыт словами. Слова — это код, модель. (Карта, если хотите.) Они не могут передать реальность (опыт) полностью. Какие-то ошибки, кажется, просто невозможно «осознать, не сделав».

Хороший ментор в состоянии оценить мой уровень и сделать вывод о том, какие вещи я смогу понять, просто обсудив их, а какие — пока нет.

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

Такие задачи ставят в ступор и могут привести к параличу анализа, когда принять решение вообще не получается: ru.wikipedia.org/wiki/Аналитиче…

Менторы, как более опытные разработчики, могут поделиться опытом решения подобных задач. Прекрасно — если они уже решали именно такие задачи, пробовали разные решения и знают, какие именно проблемы несёт каждое из них. (Причём особенно полезно знать проблемы в будущем.)

Но даже если нет, чем больше разнообразного релевантного опыта, тем больше шансов выбрать оптимальное решение для задачи.

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

- ...Как управлять по-настоящему большими кодовыми базами? - Как управлять людьми, как делить нагрузку, на что обращать внимание? - Да много чего ещё. Когда я сталкивался с подобными задачами сам, было трудно именно принимать решение.

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

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

Кстати! Как вы считаете, какими навыками должен обладать хороший ментор? Понятно, что уметь разжёвывать сложное простым языком — это хорошо. А ещё? 😃

Можем подвести предварительный итог ^_^ Нужны: - эмпатия и этика; - умение поставить себя на место ученика; - планирование и умение подмечать ошибки; - Т Е Р П Е Н И Е 😃

Скоро закончу с задачами на работе и вернусь, чтобы обсудить опен-сорс 😃

Ну теперь давайте поговорим и об опен-сорсе! У меня опыта в трушном™ опен-сорсе нет. Весь мой Гитхаб — это пара небольших пакетов да исходники книг: github.com/bespoyasov/

И я, если честно, не очень понимаю, как эффективно расти через опен-сорс, особенно если я новичок. Я когда был джуном и смотрел в чьи-то репозитории, думал разве что в документацию законтрибьютить, да и то — непонятно, как: я ж код не понимаю.

Просить объяснить я не могу, потому что просто так буду отнимать у людей время — они же занимаются опен-сорсом в свободное время, им за него (в большей части) не платят.

Просто присылать пул-реквесты — тоже нутакое. Мейнтейнерам придётся не только отвлечься, но ещё и накатать какой-то фидбек, почему мой пул-реквест не подходит.

Остаётся — делать какие-то библиотечки и пакетики, которые будут кому-то полезны. Первым у меня был groontograf — типограф для Grunt (я старый 😃): - github.com/bespoyasov/gro… Но я его быстро забросил.

Было ещё приложеньице для конвертации дат в таймштампы и обратно. Кому-то вроде даже было полезно. Но опять-таки, я и его забросил, потому что из фидбека была одна ишья и всё 😃

Из каких-то более полезных вещей: Букмарк, скриптик для навигации по странице - bespoyasov.ru/bookmark/ Прокрутчик (единственное, что до сих пор частично поддерживаю) - bespoyasov.ru/scroller/ Но это всё не помогало расти ¯_(ツ)_/¯

Собственно вопрос: в чём секрет роста через опен-сорс? Как это делать? Как это делать этично, чтобы никому не досаждать? Возможно ли это в принципе? 😃 Поделитесь опытом :—)

Давайте начнём с университета ¯_(ツ)_/¯ Я понимаю, что не мне с моим дипломом Уфимского технического говорить об университетском образовании, но тем не менее.
Плюсы и минусы университета: twitter.com/jsunderhood/st…

Курсы! 😃 Я проходил какие-то курсы на Udemy и где-то ещё. Тут могу сказать, что любые новые знания с курсов надо сразу пробовать включать в работу. Потому что иначе всё быстро забудется, и толку не будет.
О курсах программирования: twitter.com/jsunderhood/st…

Идём к самому интересному 😃 Давайте следующим пунктом выберем боевую разработку.
Боевая разработка — помогает расти: twitter.com/jsunderhood/st…

Продолжим! Расскажу, почему я считаю, что ментор нужен, почему не только джунам и почему боевая разработка без менторства растит медленнее.
Зачем нужны менторы и не только джунам: twitter.com/jsunderhood/st…

Ну теперь давайте поговорим и об опен-сорсе! У меня опыта в трушном™ опен-сорсе нет. Весь мой Гитхаб — это пара небольших пакетов да исходники книг: github.com/bespoyasov/
Как расти через опен-сорс? twitter.com/jsunderhood/st…

Завтра утром подведём итоги сегодняшнего опроса из начала треда и начнём говорить о технических блогах ^_^ - Зачем вообще вести, и как начать писать; - Насколько глубоко уходить в детали в постах; - Свой хостинг или блогоплатформа; - На каком языке писать и другое.

Это первый тред, который не сломался за день ни в одном месте 😅

Пятница


Итак, самое большое влияние оказала боевая разработка. Ментор на втором месте, университет и курсы — на третьем.
notion image

🔥Тред (@bespoyasov)
Давайте под конец рабочей недели поговорим о ведении технического (и не только) блога! - Зачем вообще вести, как начать писать; - Насколько глубоко уходить в тех. детали в постах; - Свой хостинг или блогоплатформа; - Русский или английский язык. Кидайте ссылки на свои блоги!

Расскажите, ведёте ли вы свой блог? как начинали? что подтолкнуло? что для вас самое сложное? какие плюшки вы от блога получаете?

Я пока начну и расскажу о своём блоге: bespoyasov.ru/blog/ Начал я его вести примерно тогда же, когда начал работать. Правда, самые первые посты не сохранились, мой первый пост сейчас 2012 года. Причин «зачем это надо» могу назвать штук 6. Сейчас пройдёмся по каждой :–)

Блог помогает бороться с внутренним самозванцем. Как проверить гипотезу, что я «ничего не знаю и не умею»? Попробовать её опровергнуть. Статья, твит, пост — всё это собирает фидбек, из которого можно составить чуть более объективную картину мира.

Бывает, правда, кажется, будто писать не о чем. «Все обо всём уже давно написали, и смысла повторяться нет.» Пишите всё равно! - Не все читали то, что читали вы, кому-то это будет полезно. - У вас могут быть детали, которых не было в других постах. - ...

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

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

...Если нет, то это повод перечитать книгу и дополнить конспект. Потом я подумал, чего б не делать конспекты хороших книг публичными? Вдруг кому-то ещё зайдут. Один из последних конспектов по Петцольду — зашёл 😃 bespoyasov.ru/blog/code-the-…

Ну и в целом в блог я иногда скидываю удачные приёмы, которые особо больше негде хранить. Например, вот пост-сниппет об обработке ошибок: bespoyasov.ru/blog/error-han… Или инструкция к описанию багов: bespoyasov.ru/blog/cant-repr… Удобно, что оно доступно глобально без аутентификации.

Стандартный ответ на вопрос. Стабильно выкладывать посты я начал после того, как пришёл преподавать в Нетологию. Я проверял домашки и вёл дипломы, из-за чего мне приходилось часто отвечать на одинаковые вопросы.

Я начал собирать стандартные ответы в заметочку, которую потом использовал как шаблон. О шаблонах и инсайдах я потом написал подробный пост 😃 bespoyasov.ru/blog/one-and-a…

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

Из таких стандартных ответов могу вот привести: - Как описывать баги bespoyasov.ru/blog/cant-repr… - О документации bespoyasov.ru/blog/documenta… - Копипаста в коде - bespoyasov.ru/blog/copy-past…

Это работает почти как Гитхаб! Блог часто приносит мне хорошие офферы и освобождает меня от собесов ¯_(ツ)_/¯ Я сам офигел, когда такое в первый раз произошло 😃 Как там сейчас модно говорить — личный бренд? Это вот оно как раз.

Это хороший тренажёр для формулировки мыслей. Я заметил, что после какого-то времени ведения блога, у меня получается на письме хорошо формулировать мысли и задачи. С задачами вообще огонь, потому что хорошая формулировка проблемы — половина решения.

Это, правда, почти не повлияло на мою устную речь. Этот навык надо, видимо, отдельно развивать 😅

Поле для дискуссий. Вообще, я сейчас стараюсь так не делать, но вначале, если меня что-то возмущало, я мог написать статью об этом. Например, вот: bespoyasov.ru/blog/how-to-in… Но сейчас мне это кажется треш-толком, поэтому реактивных на что-то постов стараюсь не писать.

@jsunderhood ЖЖ -> Wordpress.com -> Standalone WP -> ЭГЕЯ -> 11ty. Самое сложное: вести и не забывать. Это же не твиттер. Я трижды получал оффер из-за блога.
Офферы — жизненно! У меня тоже большая часть офферов из блога: twitter.com/jsunderhood/st… twitter.com/furtivite/stat…

@jsunderhood Я такой: о. Вот это надо написать. Открываю ношн, сажусь писать, отвлекаюсь, возвращаюсь, читаю, нудятина какая-то, не буду писать. Или потом напишу... pic.twitter.com/fpbfhRCx1v
О том, как не отвлекаться, сегодня тогда тоже поговорим :–) twitter.com/furtivite/stat…

А сейчас поговорим о том, как вытащить из себя статью. - Что делать, если я постоянно отвлекаюсь? - Как и когда редактировать? - Насколько уходить в детали, если есть примеры кода?

Итак, у меня есть идея для статьи. Я сажусь её писать, и... То чаю захотелось, то в Твитере что-то интересное пишут, то пишу, но получается нудно, скучно, и вообще, писательство — не моё, ну его нафиг. Знакомо.

Есть три принципа, которыми я пользуюсь, чтобы избегать ступора, прокрастинации и разочарования: - «Есть слона по частям» - «Ну блин короче...» - «Редактировать — отдельно» Разберём каждый.

Я замечал за собой, что прокрастинирую я те задачи, которые кажутся большими, объёмными и непонятными. Новый пост — это та ещё непонятная задача. Сами посудите: - с чего начать? - как сформулировать проблему? - какая аудитория? - что читатели должны знать перед прочтением?

Все эти вопросы так или иначе возникают при написании статьи. Просто мы можем не отдавать себе отчёт, что они есть. Но фоном мы всё равно будем пытаться на них ответить ¯_(ツ)_/¯

Первый принцип «Есть слона по частям» старается разбить большую непонятную задачу на маленькие куски. Такие маленькие задачи можно решить по одной за раз. Ну типа, - «определиться с проблемой»; - «определить уровень знаний перед прочтением»; - и т. д.

Этот же принцип я применяю при собственно написании текста статьи. Я не пишу сразу огромную портянку на 40 тысяч символов — это сложно, выматывает и вообще. Сперва я намечаю структуру заголовков — это помогает составить «карту», по которой я потом буду идти.

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

@jsunderhood давно хочу писать тех блог, но торможу, кажется, ну что нового я могу еще сказать? хотела писать про свои муки при обучении, а кому это надо? так и не решилась. Петцольд рулит, да.
Муки при обучении — вообще топ-тема, и вот почему: Учителя прокляты знаниями ru.wikipedia.org/wiki/Проклятие… Они иногда просто не могут поставить себя на место ученика, чтобы осознать, почему их объяснение непонятное. twitter.com/coderzephyr/st…

Статьи из разряда, «мы столкнулись с такими проблемами» помогают открыть глаза на эти вещи. Помочь кому-то ещё увидеть, что не только у них такие проблемы. Я свой первый пост о страхе потерять работу тоже считал никому не нужным и бесполезным: bespoyasov.ru/blog/fight-fea…

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

@jsunderhood Ну, получается, хорошее время для анонса — я завел блог. Пишу про фронтенды, JS и архитектуру. blog.kamyshev.me/?utm_campaign=… Подписывайтесь, рассказывайте друзьям.

А сейчас поговорим о том, как вытащить из себя статью. - Что делать, если я постоянно отвлекаюсь? - Как и когда редактировать? - Насколько уходить в детали, если есть примеры кода?
Разворачиваю тему в основном треде 🧵 twitter.com/jsunderhood/st…

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

И тут наступает проблема «белого листа» — С Ч Е Г О Н А Ч А Т Ь ? 😃 Используйте второй принцип: «ну блин короче». Начните ваш текст поста с «Ну, блин, короче...» и дальше пишите всё, что считаете нужным.

Пишите просто сплошняком, без абзацев, без разбиения на предложения. Строчите из буквомёта, пока идёт. Не беспокойтесь, вы это отредактируете, но потом: Третий принцип «Редактировать — отдельно».

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

Всё это встаёт в прямое противоречие с «написанием». Можно сравнить написание с брейм-штормом, а редактирование — с анализом результатов.

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

Важно: во время перерыва я не смотрю на то, что написал. Вообще. Если я отдыхаю от текста, то не вспоминаю о нём до следующего подхода. Даю, так сказать, нейронам остыть.

В следующий раз, когда я сяду за текст, я буду отдохнувшим от него (что позволит найти ошибки и нелогичное повествование). А ещё такая перезагрузка, вероятно, даст время дефолт-системе мозга поработать за меня: ru.wikipedia.org/wiki/Сеть_пасс…

Забавно, но именно во время мытья посуды или прогулки я придумываю хорошие доводы и сравнения для своих статей ¯_(ツ)_/¯

Хорошо, вот за несколько подходов мы наполнили структуру из заголовков каким-то текстом. Там нет абзацев, иногда нелогичные переходы, предложения не согласованы, вот это всё. Что дальше? Дальше можно начать редактировать.

Я обычно сперва проверяю логику повествования: - логично ли одно предложение перетекает в другое? - движется мысль или стоит на месте? - как связан один абзац со вторым и т. д.

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

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

После того, как текст становится монолитом, где ни убрать, ни добавить, можно приступать к пунктуации, орфографии и грамматике.

@kumma_kirill @jsunderhood Я вот мигрировал с Медиума на свой сайт ☺️
Поддерживаю собственные сайты! (Об этом тоже будет тред 😃) twitter.com/kamyshev_code/…

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

Днём поговорим о том, что выбрать: - свой хостинг или чью-то платформу; - русский или английский язык.

Продолжим 🙂 Давайте ещё один опрос! Self-hosted блог или чья-то платформа?
🤔 75.9% Селф-хост 🧑‍💻
🤔 24.1% Блого-платформа ✍️

Я топлю и всегда топил за селф-хост. У платформ я вижу только одно преимущество — можно сразу писать на какую-то аудиторию. Всё, дальше только минусы 😃

- Контент — не мой; - Площадка может на мне наживаться и вообще вести себя по-скотски (привет, Медиум!); - Если площадка большая — пост теряется среди тысяч других; - Не всегда удобно писать и публиковать.

Я писал немного на newline и сейчас пробую dev.to в рамках эксперимента, чтобы выйти на зарубежную аудиторию, посмотреть чё-как, почву прощупать. Но уже сейчас понимаю, что мне, вероятно, придётся делать английскую версию сайта :–/

В селф-хосте мне нравится, что контент всегда остаётся у меня и в одном месте. Я могу переехать со своими заметками куда захочу, устроить процесс публикации, как мне удобно: - bespoyasov.ru/blog/new-site-…

— Но для селф-хоста нужен дизайн! Не-а 😃 Можно наверстать сайт на чистом HTML без стилей. Если есть, что написать, это будут читать: - ariarzer.dev

— Но для селф-хоста нужен домен и хостинг, и TLS, и деньги! Да, но не очень много: - HTTPS можно подключить через letsencrypt.org - Цена на домен зависит от зоны (.ru — дешёвые)

— Но селф-хост надо промоутить! Сарафанное радио работает не хуже, чем блого-платформы. (Говорю по опыту: - front-not-pain.bespoyasov.ru)

Кстати, насчёт сарафанного радио. У Веб-стандартов недавно появился список с инди-блогами о фронтенде ;–) - github.com/web-standards-…

— Но что, если я не буду писать? Всегда можно сделать архив с заметками и опубликовать их в тех же gist на Гитхабе, если вы поймёте, что держать свой блог невыгодно или не хочется.

— Но я не хочу кодить, я хочу просто писать! Если не хочется много кодить, то можно посмотреть на генераторы типа 11ty.dev или чего-то похожего. Если кодить не хочется совсем, то да, наверное, селф-хост не подойдёт :–)

Окей, а что с языком? 😃 На каком языке писать: русском или английском. Мне гораздо проще писать на русском и потом переводить на английский ¯_(ツ)_/¯ Я понимаю, что это контрпродуктивно, но вот так :–/

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

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

@jsunderhood dskr.dev RSS пока не написал, статьи писать лениво да и выходит кажется не очень(
Дизайн-имитация редактора кода — огонь! 🔥 twitter.com/dskr_dev/statu…

Чтобы писать на английском, я использую: - deepl.com/translator — для перевода, умеет в идиомы, понимает контекст (лучше Гугла 😃) - app.grammarly.com — для проверки грамматики и орфографии, помогает расставлять запятые (в английском не понятные для меня правила 😅)

Если вы пишете на платформу, где используется Markdown, то вот читщит по нему: - github.com/adam-p/markdow… (У картинок сначала — квадратные, потом круглые скобки 😅)

В общем, не повторяйте моих ошибок, пишите сразу на английском 😃

Отправляюсь работать. После поговорим об RSS (надо / не надо) и как вставлять примеры кода (нужна ли подсветка, сколько кода — слишком много кода).

Продолжим 🙂 Давайте ещё один опрос! Self-hosted блог или чья-то платформа?
Развернул тему в основном треде 🧶 twitter.com/jsunderhood/st…

Продолжим! RSS — надо или нет. До сих пор считаю, что ничего лучше для подписки на блог не придумали 😃 А когда появились «умные» ленты, без RSS стало вообще нереально ничего читать.

Не у всех платформ RSS есть, и в селф-хосте добавить его тоже бывает сложно. Мне вот пришлось писать собственный скрипт для генерации ленты: - bespoyasov.ru/blog/new-site-… - github.com/bespoyasov/www…

Но RSS для меня — единственное место, где блоги читать удобно. Почта — для работы, я сейчас наоборот чищу почту ото всяких рассылок, чтобы не шумели. Соц. сети — возможно, но там нужно следить самостоятельно, не пропустил ли чего. Это неудобно.

Поэтому для меня ответ однозначный — да, RSS нужен. Старческое кряхтение.

А теперь о примерах кода 😃 Вот мы пишем статью о какой-то технологии или случае из разработки. Там будет код. Как его правильно оформить?

Нам же одновременно надо решить почти противоречащие задачи: - Кода должно быть не слишком много, чтобы было проще читать. - Но кода должно быть достаточно много, чтобы передать контекст проблемы.

- Код должен быть не слишком сложен и специфичен, чтобы пример был проще для понимания. - Но код должен быть достаточно специфичен, чтобы не быть примером а-ля 2 x 2 = 4. - Как быть с примерами, которые нельзя разделить на более мелкие? - Добавлять ли слишком мелкие примеры?

Начнём с простого. — Добавлять ли простые и маленькие примеры? Да, лучше добавить. Это как в кино, лучше показать, чем рассказать. Иногда парой строк кода можно выразить больше, чем несколькими абзацами текста. Но при этом объяснения к коду тоже стоит привести.

— Писать объяснения до примера, после или внутри? Расположение не имеет значения, но последовательность — имеет. Лучше выбрать для себя правило и следовать ему на протяжении всего поста. Вопреки расхожему мнению, я считаю, что пояснения внутри кода в виде комментариев — хорошо.

Хорошо, потому что объяснение находится прямо в том месте, которое объясняет. Лучше написать комментарий перед строкой с объяснением, чем потом писать «А на 6-й строке мы делаем бла-бла».

Мне ещё кажется, это более привычно для читателей, потому что они сами видят комментарии именно в таком виде на работе.

— Как выбрать, какой код добавлять в статью? Я стараюсь добавлять код, который относится непосредственно к теме статьи. Читаю заголовок или подзаголовок, задаю себе вопрос: «Этот код относится к теме?» Да — добавлю, нет — в топку его, иначе будет шуметь.

— Что делать с примерами, которые не делятся? В первую очередь подумать, можно ли это отрефакторить. Затем подумать, как бы вы группировали такой код отступами в редакторе. Где добавите пустые строки — там можно выделить отдельный кусок.

Теперь самое сложное: — Как выбрать, какой именно код и сколько код приводить в примерах? Откусывайте от кода маленькие кусочки до тех пор, пока откусить будет больше нечего.

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

Акцентируйте внимание на развитии примера сквозь статью. Давайте на примере моего поста о DI: - bespoyasov.ru/blog/di-ts-in-…

Показываем предпосылку к идее на простом примере кода: (Зависимости — это как аргументы.)
notion image

Обращаем внимание на детали, которые помогут вникнуть в идею позже: (Кроме аргументов мы используем глобальный объект — зависим от него.)
notion image

Приводим читателей за руку в собственно идею: (Такие зависимости тоже можно передавать явно. Обратите внимание, что внутренности функции спрятаны за многоточием, они здесь не важны.)
notion image

Этот же кусок кода мы дальше используем, как опорную точку для развития идеи: (Важно описать поведение, не важно, какой именно объект использовать.)
notion image

@jsunderhood I write books amazon.com/gp/product/B08…
Или даже так! 😃 twitter.com/artyudin_nyc/s…

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

Давайте под конец рабочей недели поговорим о ведении технического (и не только) блога! - Зачем вообще вести, как начать писать; - Насколько глубоко уходить в тех. детали в постах; - Свой хостинг или блогоплатформа; - Русский или английский язык. Кидайте ссылки на свои блоги!
Пятница; говорим о технических блогах, зачем вести, как, что это даёт: twitter.com/jsunderhood/st…

Я пока начну и расскажу о своём блоге: bespoyasov.ru/blog/ Начал я его вести примерно тогда же, когда начал работать. Правда, самые первые посты не сохранились, мой первый пост сейчас 2012 года. Причин «зачем это надо» могу назвать штук 6. Сейчас пройдёмся по каждой :–)
6 причин, для чего вести: twitter.com/jsunderhood/st…

А сейчас поговорим о том, как вытащить из себя статью. - Что делать, если я постоянно отвлекаюсь? - Как и когда редактировать? - Насколько уходить в детали, если есть примеры кода?
Как помочь себе начать писать и довести статью до конца: twitter.com/jsunderhood/st…

И тут наступает проблема «белого листа» — С Ч Е Г О Н А Ч А Т Ь ? 😃 Используйте второй принцип: «ну блин короче». Начните ваш текст поста с «Ну, блин, короче...» и дальше пишите всё, что считаете нужным.
Проблема белого листа
: twitter.com/jsunderhood/st…

Продолжим 🙂 Давайте ещё один опрос! Self-hosted блог или чья-то платформа?
Self-hosted блог или блого-платформа: twitter.com/jsunderhood/st…

Окей, а что с языком? 😃 На каком языке писать: русском или английском. Мне гораздо проще писать на русском и потом переводить на английский ¯_(ツ)_/¯ Я понимаю, что это контрпродуктивно, но вот так :–/
Какой выбрать язык: twitter.com/jsunderhood/st…

А теперь о примерах кода 😃 Вот мы пишем статью о какой-то технологии или случае из разработки. Там будет код. Как его правильно оформить?
Как добавлять примеры кода: twitter.com/jsunderhood/st…

@jsunderhood 1. Веду defront.ru 2. Хотелось сделать базу прочитанных статей, ну и всегда было интересно делиться информацией :) 3. Найти хорошую тему 4. Сейчас по сути блог — моя основная работа
Блог — может стать основной работой! 🔥 Кстати, спасибо на defront — огнище огненное ^_^ twitter.com/myshov/status/…

Продолжим 🙂 Давайте ещё один опрос! Self-hosted блог или чья-то платформа?
Подъехали результаты опроса: большая часть тоже топит на селф-хост! twitter.com/jsunderhood/st…
notion image

Ну и предлагаю сегодня закончить пораньше — пятница всё-таки 😃

🔥Тред (@bespoyasov)
Хорошая статья не обязана быть большой. Можно писать небольшие заметки о деталях разработки, о которых не все знают или помнят: - mefody.dev twitter.com/unetwarm/statu…

Ещё мне не нравится идея равнять возможности всех людей под какой-то «стандарт». Можно писать хорошие статьи раз в месяц, можно раз в две недели — всё упирается в навык, который можно развить.

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

@jsunderhood Давно хотел, недавно собрался и запилил на Gatsby + vercel: blog.beraliv.dev Пишу про TypeScript, т.к. есть опыт, нравится и на работе у нас есть встреча на 15 мин, где проблемы поднимаем. Решаю задачки с #typechallenges, расписываю решения, пишу на английском
Шрифт кайфовый! За TypeScript — жирнейший плюс ^_^ twitter.com/beraliv/status…

Суббота


@jsunderhood Сейчас работаю над сборником решений для type-challenges ghaiklor.github.io/type-challenge…

@jsunderhood Статьи: habhub.hyoo.ru Видео: youtube.com/channel/UCwRUy…
Про инверсию зависимостей на голом TS интересно: twitter.com/jin_nin/stat…

@jsunderhood Вопрос о комментариях. Своеобразная обратная связь в блоге, кто то использует «сообщить об ошибке», кто то прикручивает сторонние сервисы комментариев. Что думаете о их пользе и необходимости? Как понимать «успех» и пользу постов на инди-блоге, принимать советы и замечания?
Мне очень лень пркручивать комменты к блогу, хотя надо бы :–/ Антон Жиянов недавно писал об относительно просто способе развернуть комментарии: - antonz.ru/comments-via-g… У меня задача лежит в «сделать позже», но дойду ли до неё ¯_(ツ)_/¯ twitter.com/IvanSupervan/s…

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

@jsunderhood Как только стал активно менторить необходимость в повторении материала на разных людей выросла и стало очевидным что его нужно где то закрепить, свой блог может стать таким местом👍
Да, я стал регулярно писать, именно когда стало нужно ссылаться на ответы о чём-то. - bespoyasov.ru/blog/one-and-a… twitter.com/AntonK52/statu…

@jsunderhood Выкладываю публичные заметки на гитхаб github.com/antonk52/webde…
Тоже вариант! Из них потом при желании можно вырастить какой-нибудь бложек. twitter.com/AntonK52/statu…

Доброе утро субботы! ^_^ Давайте сегодня поболтаем о пет-проектах? - Как относитесь к идее пет-проектов вообще: положительно, отрицательно? Почему? - Работаете ли над ними? - Над какими? Чем гордитесь? - Как появилась идея?

Сейчас я постараюсь проснуться и начну 😅


@jsunderhood Пет проекты — это хорошо. Знаю компании, которые ищут себе сотрудников только по пет-проектам.
А что вы думаете о такой практике? Мне кажется, это несколько завышенные требования от разработчиков. Объясню в треде ↓ twitter.com/furtivite/stat…

Я иногда задумываюсь, а не становятся ли пет-проекты и опен-сорс обязательным (и завышенным) требованием при найме? Меня на эту мысль натолкнул пост Марка Симанна “The Dispassionate Developer”: - blog.ploeh.dk/2021/03/22/the…

Пет-проекты — это с одной стороны, способ улучшить свои навыки. А если сойдутся звёзды — то и разбогатеть на мега-супер-ультра-убер-крутом стартапе. Но с другой — это всё же работа забесплатно.

Одно дело, когда я горю идеей что-то сделать и попробовать; и совсем другое — когда от меня этого требует вакансия.

Тем более что не во всех компаниях выделяют время на опен-сорс или пет-проекты. Так вроде только в Гугле делали (или где-то ещё)? - inc.com/adam-robinson/…

У меня из пет-проектов самый долгий (и известный) — это Тяжеловато: - fuckgrechka.ru/tzlvt/

Мы его делали с @Yumadilov, когда нам не на что было выживать 😃 Оттуда и название и дефолтный лимит в один прожиточный минимум 😅

Разработку вели открыто. Прямо перед началом объявили, что сделаем приложение за две недели и начали об этом писать: - blog.yumadilov.com/all/tyazhelova… - notes.yumadilov.com/all/tzlvt-hist… Я писал о технической стороне прямо во время разработки. - bespoyasov.ru/blog/tyazhelov… - bespoyasov.ru/blog/tyazhelov…

Примерно тогда же я начал тыкать в электрон и в курс доллара и сделал Курсовик 😅 - bespoyasov.ru/blog/kursovik/ Я его сразу перестал поддерживать. Но недавно он переродился в приложение на React Native: - expo.io/@bespoyasov/pr… ...Которое я тоже с успехом забросил 😃
notion image

А затем я вообще использовал идею курсовика как основу для воркшопа о тестировании реакт-приложений: - bespoyasov.ru/talks/?full#1 Так что можно сказать, что проект как феникс, перерождался уже 3 раза 😅

Пробовал делать инструменты для разработчиков. Один из тех, которыми пользуюсь сам — Тмстмп: - bespoyasov.ru/tmstmp/ Переводит даты в таймштампы и обратно. Поддерживает разные форматы и периоды.

Один из тех, которым пользуюсь не только я, — Прокрутчик: - bespoyasov.ru/scroller/ Скрипт для прокрутки контента на сайтах.
notion image

@jsunderhood Не особо, все продвигается оч медленно pic.twitter.com/pOqvT0wBP3
Оно живое! 🤖 twitter.com/UntrueMe/statu…

А дальше меня как-то переключило на книги ¯_(ツ)_/¯ Первым таким пет-проектом-книгой стало «Фронтенд — это не больно!»: - bespoyasov.ru/front-not-pain/

Изначально я хотел сделать доклад, но потом понял, что не хватило бы времени на всё. Так вместо презентации появился огромный гугл-док, в котором я накидал вообще всё, что было сказать по теме 😅 Потом мы с @Yumadilov и @andrew__romanov прошлись по контенту...

...Пофильтровали его, подчистили. На новогодних каникулах я всё сверстал и насобирал мемов для иллюстраций. В конце зимы мы его выпустили ^_^

Недолго после этого я проходил какой-то курс о тестировании, где затрагивали тему TDD. Затрагивали очень поверхностно, а мне хотелось разобраться посерьёзнее. Так появилось TTT-TDD: - bespoyasov.ru/ttt-tdd/ Книжка о TDD на примере разработки Крестиков-ноликов.

Я стащил идею расположения текста и кода отсюда: - glebec.github.io/lambda-talk/ (Сейчас кажется, что ещё неплохо было бы зацветокодировать зону соответствующим цветом, но никак руки не дойдут.)
notion image

Когда я начал заниматься проектированием и чуть чаще работать с ООП, я понял, что не понимаю принципов SOLID. Тогда мы с @dex_157 сделали Солидбук: - ota-solid.vercel.app

Мы решили не просто рассказать о принципах, но ещё и показать их действие на примерах в коде, в жизни и в паттернах. Подобрали случаи из собственных проектов, где принципы могли бы помочь; насобирали паттернов и антипаттернов с запахами кода.

Всё остальное либо не дожило до наших дней, либо не развивается и не поддерживается 😅

🔥Тред (@bespoyasov)
С опен-сорсом проще: иногда работа внутри компании позволяет релизнуть что-то в опен-сорс. А вот с пет-проектами не так. В общем, что вы думаете: - нормально ли требовать от разработчиков при найме куда-то пет-проекты? - если да, то при найме куда?

🔥Тред (@bespoyasov)
@UntrueMe @jsunderhood Не так прикольно как с роботом гексаподом выглядит, но это мой пет. Это система автоматизации отопления дома на джаве. Взаимодействие через телеграмм бот. Управляет обогревом дома в зависимости от температуры на улице, времени суток и наличия людей в комнатах. pic.twitter.com/dL6TU6U46b

А почему заниматься ремеслом ради выгоды — плохо? Ведь можно вкладываться и делать хорошо одно дело, на работе, в рабочее время. Рабочими проектами тоже можно хвастаться. twitter.com/kra1g0/status/…

Я не стараюсь набросить, а скорее разобраться, что побуждает смотреть при найме не только на результаты работы, но и ещё на что-то. Конкуренция? Культура? Скрытые выгоды?

@jsunderhood О, моя любимая тема marat.to/posts/2021-01-…

Мне понятная мотивация компаний, которые ищут трудоголиков, чтобы те работали по 240 часов в сутки. Мне понятна мотивация компаний, в которые на одно место претендуют 100 человек. Но мне не будет понятен тренд требовать пет-проекты при найме по умолчанию, если он появится :–/

@YouSysAdmin @jsunderhood 2/2 Что мешает выпускнику переписать его на React или Vue, которые он прошел позднее? Выделит ли это его работу среди других многочисленных даже без петов? Да, определённо. Но этим никто не занимается.
Идея использовать пет-проект, как площадку для оттачивания навыков, которые студент приобретает во время обучения, мне нравится. Это можно рассматривать, как собственно обучение, это не отъедает времени сверх. twitter.com/furtivite/stat…

@jsunderhood Я постоянно какие-то пишу, только жалко, что часто забрасываю. Но вообще, часто бывает, что пет проекты намного интереснее всех других дел, даже работы. К тому же, в процессе можно выучить новые технологии. Я так сейчас учу Vue, Python Flask и Docker
Заметил, кстати, что часто упоминают, будто пет-проекты интереснее основной работы 🤔 Нужно ли с этим бороться? Как? twitter.com/kumma_kirill/s…

У меня возникает мысль «найти работу интереснее», но это не всегда возможно. Отчасти как раз потому, что не всегда можно устроиться на тот стек, который интересен, без опыта 🤔

@jsunderhood Раньше вёл блоги про веб, про кино, про игры. Всё кануло в Лету. Остался только Твиттер. И, с недавних пор, видеоблог, но совсем не про ИТ :: youtube.com/channel/UCPhc2…
Видео-блоги — тоже блоги 😎 twitter.com/webholt/status…

Доброе утро субботы! ^_^ Давайте сегодня поболтаем о пет-проектах? - Как относитесь к идее пет-проектов вообще: положительно, отрицательно? Почему? - Работаете ли над ними? - Над какими? Чем гордитесь? - Как появилась идея?
Суббота — пет-проекты и всё рядом: twitter.com/jsunderhood/st…

🔥Тред (@bespoyasov)

Воскресенье


В @jsunderhood затронули тему личных блогов. Блог это классно, вот только где тот самый гугл ридер, в котором собирать бы все rss? Кажется, читать личные блоги стало неудобно. Нет подписки, нет комментов, потому что «кому они нужны». Да и авторов писать в пустоту не мотивирует
Я обычно RSS с телефона читаю, а для него есть великолепный Reeder: - reederapp.com twitter.com/denis_f_l/stat…

@jsunderhood По-моему формат с телеграм каналом, в котором собраны заголовки и ссылки, самый удобный (для читателя)
Вполне вероятно. Хотя я пробовал вести канал в Телеграме, показалось неудобным писать туда 🤔 (А ещё когда я блог начинал, Телеграма ещё не было ¯_(ツ)_/¯) twitter.com/not_a_reptiloi…

Сегодня воскресенье, давайте подводить итоги недели!

Теперь немного о собственно проектировании. Допустим, мы знаем, что нашему проекту нужна суровая масштабируемость. Что делать? Первым делом стоит взять ручку, бумажку и пойти «программировать ногами» 😃 twitter.com/lizuschiykotik…
Понедельник начали с обсуждения архитектуры и DDD. Обговорили, нужная ли чистая архитектура на фронте и как делать код на слои; попрактиковались в практическом проектировании: - twitter.com/jsunderhood/st… - twitter.com/jsunderhood/st… - twitter.com/jsunderhood/st…

Доброе утро! Сегодня вторник, а значит поговорим об ООП на фронте. Пока я заливаю в себя кофе, давайте проведём опрос. Как вы думаете, ООП и фронтенд:
Во вторник обсудили ООП. ООП и фронтенд — хорошие друзья или заклятые враги. Как ООП помогает проектировать архитектуру приложений. twitter.com/jsunderhood/st…

А сегодня поговорим о том, как сделать код читаемым и тестируемым ^_^ Расскажите о своих приёмах, как вы улучшаете кодовую базу на проектах? Какие применяете методы, принципы, эвристики? Я пока начну 🧶
В среду поделились рецептами, как делать код читаемым и тестируемым. TDD, работа с легаси, принципы и эвристики. twitter.com/jsunderhood/st…

Доброе утро четверга! ^_^ Чем ближе конце недели, тем больше мы уходим от хард-скилов 😃 Сегодня поговорим о том, где разработчикам набираться опыта, вообще и эффективнее всего. Опрос! Что из перечисленного оказало на вас сильнейшее влияние?
В четверг поговорили о том, как в разработке эффективнее всего расти: - через боевую разработку, - ментора, - университет и курсы - или опен-сорс. twitter.com/jsunderhood/st…

Давайте под конец рабочей недели поговорим о ведении технического (и не только) блога! - Зачем вообще вести, как начать писать; - Насколько глубоко уходить в тех. детали в постах; - Свой хостинг или блогоплатформа; - Русский или английский язык. Кидайте ссылки на свои блоги!
В пятницу обсудили, как и зачем вести технический блог: twitter.com/jsunderhood/st…

Привет! На этой неделе у микрофона Саша @bespoyasov. Работаю в DRIVE2. Пришёл туда как фронтендер, потом писал бекенд, а сейчас занимаюсь R&D проектами с анализом текста и компьютерным зрением 😃
Навигацию по подтемам и аспектам я оставил в основном треде 🧵 twitter.com/jsunderhood/st…

Спасибо всем, кто читал, отвечал и участвовал! Вы все классные.

🔥Тред (@bespoyasov)
@jsunderhood @kumma_kirill Нужно учиться работать достаточно эффективно когда работа скучна. Для этого нужны хобби и вообще насыщенная жизнь вне работы.
Мне помогает относиться ко скучным задачам как к таким типа «мета-задачам», как сделать работу нескучной. Писал об этом в: - bespoyasov.ru/front-not-pain twitter.com/mr_mig_by/stat…

Ну или относиться к работе, как к ремеслу, если первое не срабатывает. (Только главное к себе прислушиваться, вдруг мне вообще не по душе то, что я делаю.)

В общем, тред про блоги в @jsunderhood и ссылки на ридеры меня так вдохновили, что я засел с блокнотом, чтобы набросать идеи постов. Ну потом конечно еще и блог надо сделать, но это после
Огонь! Пусть всё получится! 🙌 twitter.com/denis_f_l/stat…

Ссылки