#5: Солидные скиллы: soft skills, SOLID
Продолжение разбора «Программиста-прагматика»: каша из топора и сваренная лягушка, good enough software, портфель знаний, техники критического мышления и почему коммуникация — половина работы инженера. Во второй части Александр Пахомов разбирает SOLID не по учебнику, а по практике: какие принципы он применяет каждый день (single responsibility, open-closed), к каким относится скептически (interface segregation) и почему главное в принципах — разумность, а не догма. Рекомендация выпуска — книга «Пиши, сокращай».
Главное
- Будьте катализатором изменений: не просите у людей готовый результат — услышите «нет»; начните сами, как странник с кашей из топора, и люди подтянутся со своими «ингредиентами».
- Не сваритесь как лягушка: держите «градусник» — следите за большой картиной, чтобы вовремя заметить, что проект (или вы сами) движется не туда.
- Good enough software сегодня чаще всего лучше фантазий об идеальном завтра: выпускайте раньше, собирайте фидбэк — и, как художник у картины, знайте, когда остановиться.
- Знания — это инвестиционный портфель: вкладывайтесь регулярно, диверсифицируйте, управляйте рисками (узкая экспертиза может «сгореть» вместе с технологией) и периодически ребалансируйте.
- Софт-скиллы — harder than hard: софт мы пишем для людей, поэтому нетехническая литература не менее важна технической.
- Критическое мышление по авторам: пять «почему», кто выгодоприобретатель, каков контекст (best practices — best для кого?), своевременно ли это и почему это вообще проблема.
- Одинаково важно, что вы говорите и как: плохая презентация нивелирует гениальную идею; формулируйте мысль до документа и доклада и подбирайте язык под аудиторию.
- SOLID — не догма: SRP и OCP делают код проще и расширяемым, LSP — базовая гигиена контрактов, а ISP и DIP легко довести до абсурда; соблюдайте разумность.
Ссылки
Расшифровка
[00:19] Здарова! Меня зовут Саша Пахомов, и я инженер, который любит своё дело. Это пятый выпуск подкаста «Тысяча фичей». В этом выпуске мы продолжим разбирать первую главу книги «Программист-прагматик», а потом поговорим про SOLID. В конце — самая нетехническая рекомендация за всё время. Поехали!
[00:47] Возвращался голодный странник из дальнего путешествия и пришёл в деревню. Он хотел попросить у кого-нибудь поесть: стучал в один дом, во второй, в третий — но никто ему не открыл и никто его не накормил. Тогда странник решил сварить кашу из топора. Поставил посередине деревни чан, положил туда топор и начал варить. Жители вышли — им было интересно, что происходит. «Да вот, кашу варю из топора. Было бы вкуснее, если бы добавить кусочек масла», — и кто-то принёс масло. «А ещё вкуснее — с пшеном», — и кто-то принёс пшено. Таким способом всей деревней они сварили кашу, после чего странник достал топор и насладился трапезой со всеми.
[01:32] Сейчас вы услышали мою вольную интерпретацию «Каши из топора». Именно с этой повести начинается тема в первой главе — правда, там она про суп из камней, но в переводе на наше это и есть каша из топора. К чему присказка? К тому, что если мы хотим прокачивать себя как профессионалы и менять что-то вокруг, не нужно просить людей о готовом результате: «сделайте мне удобный CI/CD», «сделайте удобные проверки в коде», «пишите мне, пожалуйста, понятные джиры». Как странник требовал готовую еду. У людей свои запары, свои задачи и свои дела — они лучше просто скажут «нет».
[02:22] А если начать делать что-то самому, не имея ничего под руками: создать эпик, описать вижен, накидать задач, сделать ресерч — начать варить ту самую кашу из топора, — может оказаться, что люди вокруг начнут подтягиваться и вносить свои вклады. И в итоге получится цельная, понятная, сложная картина — сложный продукт или нужное вам решение. Но важно понимать: оно состоялось, потому что был катализатор этих изменений. Не было бы странника с топором — не было бы и каши. Совет этого топика: будьте катализатором изменений.
[03:01] Вторая часть топика — «Сваренная лягушка». Опять аналогия, да, — но для меня она прикольная, суперпонятная и легко ложится на реалии. О чём речь? Я не ресерчил и не уверен, что это вообще правда, но давайте представим мир в вакууме: если кинуть лягушку в кипяток, она сразу из него выпрыгнет — поймёт, что это кипяток, и тем самым выживет. А если положить лягушку в холодный чан и начать кипятить, она не заметит изменений: всё происходит медленно, градусника у неё нет, она сидит себе в воде — и в итоге медленно, но верно сварится. Перекладываем на наши реалии: если не мониторить ситуацию вокруг, если нет градусника, мы как профессионалы можем немного «свариться» — оказаться невостребованными на рынке, потому что слишком долго сидели и не понимали, что происходит.
[04:21] Если меня, молодого и драйвового, закинут на проект, где используется какой-нибудь GWT, Mercurial, базу менеджат руками и пишут хранимые процедуры, — я попытаюсь что-то поменять, через неделю пойму, что ничего не поменять, кину этот проект и убегу. Но если я в этом проекте с самого начала — написал одну хранимую процедуру, другую — и не понимаю, что с проектом что-то не так, то в итоге я оказываюсь сваренным в кипятке, в который ни один свежий программист не приходит: всем понятно, что это жесть и тут работать нельзя. Совет главы: всегда думайте и помните о большой картине — о том, что происходит глобально, — чтобы понимать, в какой момент проект (или вы) движетесь не в том направлении. Имейте тот самый градусник и держите руку на пульсе.
[05:25] Следующий топик — good enough software, «достаточно хорошая программа». Хорошая — для кого? Надо определиться: хорошая для пользователей, для будущих ментейнеров, для вас лично. Она удовлетворяет требованиям — функциональным (делает то, что от неё ожидают) и нефункциональным: перформанс, privacy, security. А дальше «хорошесть» начинает размываться: для какого-нибудь инженера показатель качества — стопроцентное покрытие кода тестами (очень сомнительное мнение, но сейчас не об этом), для кого-то — полное соответствие кода SOLID-принципам, для кого-то — скорость старта программы. Думаю, вы понимаете, к чему я веду: можно до бесконечности дорабатывать продукт, делать его лучше и лучше с нашей точки зрения — но для пользователя всё это не будет иметь никакой ценности. Пользователю нужно, чтобы приложение было достаточно хорошим: решало его проблему и не доставляло лишних неудобств. Основная мысль раздела: хорошее программное обеспечение сегодня чаще всего намного лучше, чем фантазии об идеальном программном обеспечении завтра.
[07:03] Чем раньше мы выпускаем приложение, даём пользователям попробовать его и получить ранний фидбэк — тем раньше делаем корректировки. Я говорю даже не столько про мобильные приложения или сайты: там люди вроде научились — стартапы делают быстро, иногда на ноу-коде, выходят на рынок, собирают обратную связь и корректируют вижен продукта под то, что нужно пользователям. Это уже плюс-минус стандартный подход. Но я, например, бэкендер — делаю какой-нибудь внутренний программный компонент, возможно, даже для программистов: скажем, тестовый фреймворк. Я не должен выпиливать его до идеала и сидеть над ним полгода. Я могу отдать первые наброски — которые уже можно использовать и которые без багов решают свои задачи, но не идеальны, — как альфа-бета-версию: дать тиммейтам и комьюнити попользоваться и понять, куда двигаться дальше относительно их опыта, а не моего вижена. Идея в том, чтобы не упарываться по метрикам, а давать продукт быстрее и собирать обратную связь.
[08:37] В конце топика есть интересное и довольно холиварное сравнение. Нужно понимать, когда остановиться в разработке — когда мы можем сказать, что программу сделали. И здесь программирование сравнивается с рисованием, с искусством. Рисуя картину, говорят авторы, самое сложное — остановиться: можно бесконечно добавлять краски, детали, тона. Нужно знать, когда картина готова, — иначе она не будет готова никогда. То же с программированием: нужно понимать, что программа достаточно хороша, выпустить её первую версию — и перестать её идеализировать.
[09:34] Следующий топик — your knowledge portfolio, ваш портфель знаний. Начинается он с цитаты, вольно переведу: «Инвестиция в собственные знания всегда в приоритете». Авторы говорят: наши знания и опыт — самое важное, что у нас есть, мы обращаемся к ним в ежедневной работе. И что самое интересное — эта самая важная часть нас имеет свойство испаряться и терять актуальность. Десять лет назад наш конкретный опыт имел одну ценность, а сейчас он либо не имеет её вообще, либо — что чаще — постепенно теряет. С точки зрения стратегического планирования самое эффективное, что мы можем сделать, — инвестировать в умение учиться. Учиться тому, как учиться, — чтобы легко подстраиваться под изменяющиеся требования времени.
[11:06] Но как понять, что учить и как выстроить процесс? Здесь помогает аналогия с финансовым портфелем: практики управления деньгами авторы перекладывают на управление портфелем знаний. Первое — инвестируйте регулярно: это должно стать привычкой, каждый день или каждую неделю. Второе — диверсификация: не стоит вкладывать всё время в одну область. Не нужно зубрить только Spring или Java-технологии — расширяйте портфель: распределённые системы, смежные области, фронтенд, дизайн, техническое писательство. Третье — менеджмент рисков: не кладите все технические яйца в одну корзину. Можно стать глубочайшим специалистом — знать, как тюнить JVM и улучшать перформанс, быть уникальным экспертом и получать за это кучу денег. Но это огромный риск: знания могут «сгореть» — банально, JVM как технология может перестать существовать, заменится новым подходом, и огромные усилия, инвестированные в тюнинг garbage collector’а, потеряют ценность. Возможно, часть времени стоит вкладывать в другую технологию, другой скилл — может, даже другую профессию, кто знает. Четвёртое — базовая стратегия инвестиций: покупай дешевле, продавай дороже. Найдите технологии, изучение которых сейчас принесёт наибольший профит в будущем, — и не учите те, что уже теряют актуальность. Вложив кучу времени в то, как ведёт себя Postgres сейчас, через пять лет можно обнаружить, что он уже не так актуален (визионерство на себя не беру и называть ничего не буду, но идею вы поняли). И последнее — портфель нужно периодически ревьюить и ребалансировать: останавливаться и смотреть — а нужные ли вещи я читаю? Я весь год читал про распределённые системы — прикольно, но, возможно, стоит двинуться в сторону фронтенда или продуктовых вещей. Достаточно ли мой портфель сбалансирован? Совет главы вытекает из всего сказанного: инвестируйте регулярно в свой портфель знаний.
[15:19] Дальше авторы приводят челленджи — возможные идеи. Но сначала лирическое отступление. Эта книга — особенно в пересказе в подкасте — может звучать надменно: как будто она говорит, как нужно жить профессиональную жизнь, и если вы так не делаете, то вы не настоящий программист-прагматик. Полный бред, я с этим не согласен. У каждого свой путь, каждому комфортно делать то, что он считает нужным. Я считаю нужным читать профессиональные книжки, которые мне нравятся, и делиться ими с вами. Если они вам заходят и помогают что-то переосмыслить и двинуться дальше — не обязательно в моём направлении или направлении авторов, а в вашем личном — это замечательно, и я буду очень рад. А если не зайдёт и вы скажете «какая-то хрень это программирование, пойду в product management» — ещё круче. Я топлю за то, чтобы каждый понимал, чего хочет, и делал то, что ему нравится. Мне нравится то, что я делаю, — поэтому я и делюсь. Никакого высокомерия.
[17:01] Итак, что предлагают авторы. Попробуйте изучать один новый язык программирования каждый год. Читайте по одной технической книжке в месяц. Читайте и нетехнические книжки — и вот тут я бы остановился, потому что мысль суперприкольная. Большинство программистов, и я в том числе, постоянно читают техническую литературу — про распределённые системы, архитектуру, чистый код — и обсуждают её. И есть иллюзия, что именно это должен знать настоящий программист. Но чем больше я работаю, тем больше понимаю: нет — мы работаем с людьми. Мы выполняем требования людей, ходим на митинги к людям, и софт мы пишем для людей. Поэтому те самые пресловутые софт-скиллы — название, которое мне совсем не нравится, потому что нифига они не «софт», они harder than hard, — изучить их и овладеть ими, по крайней мере для меня, намного сложнее, чем хард-скиллами. Хард-скиллы простые, блин. А софт-скиллы — непонятно, и там ещё эмоции и вот это всё. Так что читать нетехническую литературу суперполезно. Полностью поддерживаю — хотя, честно говоря, сам последний раз читал «iPhuck 10» Пелевина, и это было примерно год назад. Надо, короче, почитать.
[18:41] Дальше: берите уроки. Авторы не уточняют какие — подразумеваю, что любые: хоть по барабанам, хоть спортивные, хоть по программированию. Участвуйте в локальных юзер-группах и митапах — нетворкинг; причём не просто приходить и слушать доклады, а участвовать активно: задавать вопросы, может, и самому делать доклады. Экспериментируйте с окружениями: постоянно разрабатываете в IDE — попробуйте терминал; любитель Windows — поставьте Linux и поразбирайтесь. Полностью поддерживаю: я сам разрабатываю и в IDE, и в терминале. В терминале использую Vim — считаю, чем примитивнее и ближе к терминалу инструмент, тем лучше, к тому же он установлен почти везде. А если хочу с комфортом поразрабатывать на своём макбуке, пописать тесты и покайфовать — конечно, использую IDEA. И последний тейк — держите нос по ветру: читайте книги, подписывайтесь на рассылки, слушайте подкасты, участвуйте в чатиках. Авторы говорят: читая посты и блоги, не обязательно становиться крутым в технологиях, о которых прочитал, — достаточно просто знать, что они существуют и какие там подходы: это может помочь в будущем. Просто иметь в виду — тоже очень важно.
[20:31] Дальше — два лайфхака, как применить технику постоянного обучения в рутине. Первый: возможность для обучения есть в самой профессиональной рутине. Нас стопроцентно что-то спрашивают — коллеги в чатике, близкие, кто-то в интернете. Допустим, вас спросили, как написать BeanPostProcessor, чтобы сделать что-то в Spring, — а вы не знаете. Можно ответить «не знаю, погугли», а можно сказать: «давай попробуем разобраться, я попробую помочь» — погуглить, заинтересоваться и ответить человеку через какое-то время. В итоге и человеку сделали приятно, и сами изучили новое. Честно говоря, я так никогда не пробовал — прямо за человека найти ответ и помочь разобраться; возможно, это интересно, но надо прямо очень хотеть. Второй лайфхак: берите с собой «информацию» в поездки, к врачу, в любые рутинные дела — электронную читалку, наушники с подкастом или просто телефон. Время, когда мы чего-то ждём — едем в метро, стоим в очереди, — можно проводить за чтением. Довольно очевидная мысль.
[22:19] Казалось бы, на этом можно закончить, но нет. Дальше авторы выдвигают тезис: очень важно мыслить критически. Потребляя огромный массив ежедневной информации — новости, статьи, книги, — важно понимать: то, что вы увидели статью и прочитали её, не значит, что она вам подходит, что она правдива и что она подходит вашему проекту. Не откидывайте факт, что за продвижение статьи в Google могли заплатить — кому-то интересно, чтобы технология продвигалась. Не воспринимайте всё за чистую монету. Совет логичный: анализируйте критически то, что прочли. Суперочевидно — но «критическое мышление» каждый понимает по-разному, и авторы приводят несколько техник, которые заодно проясняют, что имеют в виду они. Первая — спрашивайте пять «почему». Упал сервер — почему? Докер-контейнеру не хватило памяти. Почему? Память на машине была ограничена. А почему она была ограничена? Суть понятна: пять «почему» — и добираемся до истинных причин. В моём банальном примере причиной, скорее всего, окажется недостаточно настроенный мониторинг: мы не увидели, что память кончается, вовремя не среагировали и не накинули сверху, чтобы потом спокойно разобраться, почему приложение столько жрёт. Вот настоящая проблема — а «памяти не хватило» это лишь первый слой. Нужно погружаться дальше.
[24:39] Вторая техника — спросить: кто получает выгоду от происходящего? Если читаем статью — посмотрите на ресурс и автора. Может, это developer advocate конкретной технологии — заинтересованное лицо. Может, CEO компании, который двигает свой вижен. Это не значит «маркетинговый буллшит, читать не буду» — нет; просто учитывайте это и делайте корректировку восприятия. Третья — каков контекст? Best practices — best для кого? Для разработчиков, маркетинга, бизнеса? Некоторые статьи могут выглядеть странными или неправильными с вашей точки зрения — а погрузившись в контекст, понимаешь: это ресурс для джунов, пишет человек с годом опыта, и аудитория у материала другая. Не идите писать гневный комментарий «вы все лохи и нетрушные программисты» — просто вы не часть этой аудитории, и статья действительно не для вас. Четвёртая — где и когда это будет работать? Не слишком ли поздно, не слишком ли рано, что будет после? В каком году написана статья; не поздно ли применять описанные технологии — или, наоборот, это свежий ресерч и технология ещё слишком сырая, чтобы рассматривать её всерьёз.
[26:46] И последний вопрос критического мышления — для меня один из самых интересных: а почему это проблема? Если в статье или на проекте случилась проблема — отличный вопрос: почему это проблема? Для кого? У кого это вызывает неудобства? Проблема ли это вообще? Разбираясь, мы начинаем понимать нижележащую модель взаимодействия всего со всем и глубже погружаемся в предмет. Суперраспространённый кейс: бизнес приходит сверху и говорит — «короче, проблема, вот её решение: напишите сервис, который берёт вот это и возвращает вот это». Всегда стоит разобраться: почему это проблема, что это за проблема, для кого. Скорее всего, у вас, как у технического специалиста, окажется другое решение той же проблемы — на другом уровне, — и, возможно, вам даже не придётся писать сервис, который от вас просили.
[28:09] На этом часть про знания закончена. Последний топик на сегодня — communicate, «разговаривайте». Мысль такая: всё, что мы делаем, мы делаем для людей — и нам нужно это с ними обсуждать. Пока мы не обсудили и не предоставили сделанное людям, особой ценности оно ни для кого, кроме нас, не имеет. Огромная часть рабочего дня проходит за разговорами: митинги, переписки в чатах. И мы как профессионалы обязаны делать это эффективно. К английскому языку — а у большинства рабочий язык английский или русский — можно относиться просто как к ещё одному языку программирования: применять те же техники и практики, что и к работе с исходным кодом, — к натуральному языку, текстам, документации, dev notes, readme, комментариям. У меня был очень интересный experience: диплом я писал в LaTeX. Это совершенно другой подход к написанию текстов, очень близкий к разработке: тот же flow, можно определять блоки и переиспользовать их, следовать принципу DRY — don’t repeat yourself, использовать систему контроля версий, ревьюить. Совсем не то же, что сидеть в Word и печатать слова. Я ни за что не топлю — это личный опыт: LaTeX мне зашёл, работать с текстом как с сорцами программы — интересный, developer-friendly experience. Основной совет топика: английский — это просто ещё один язык программирования.
[30:37] Дальше: знайте свою аудиторию — с кем вы разговариваете, для кого пишете документы. С маркетингом — один язык: не стоит объяснять им, почему происходят утечки памяти и что надо заменить garbage collector, — им всё равно, они не поймут. С разработчиками и ментейнерами — другой: истории про рост продаж и revenue компании им не сильно интересны (хотя было бы прикольно, если бы были). И понимать, что за разработчики: фронтенд-отдел, бэкендеры, DBA, платформенная команда. Подбирайте вокабуляр под аудиторию. И постоянно берите фидбэк с аудитории: общаясь с командой, задавайте вопросы, пытайтесь понять, что они думают о том, что вы говорите. Обратная связь важна не только от пользователей продукта, но и от людей, с которыми вы разговариваете. Это диалог.
[31:58] Дальше — интересное рассуждение: нужно понимать, что мы хотим сказать, изначально. Это относится к докладу, к митингу, к документу — ко всему. Писатели перед книгой уже имеют наброски сюжета, знают, про что книга и какие в ней герои, — направление мысли выражено до самой книги. А что делают разработчики, когда пишут документы? Садятся за пустой Google-док, пишут слово «Introduction» — и начинают колбасить всё, что придёт в голову. Кто из вас (я в том числе) планировал, о чём будет документ и какую мысль он выразит, до его написания? Почти никто — а это было бы очень полезно: набросать верхнеуровневую структуру и понять, что человек должен узнать по прочтении. Мануал это, инструкция или предложение по улучшению системы — мысль нужно сформулировать до документа, а в документе её раскрыть. Планируйте, что хотите сказать. То же относится к митингам: завели встречу обсудить бэклог или техдолг по конкретной части продукта — поймите цель («по результатам решаем, занимаемся этим техдолгом сейчас или откладываем») и сообщите её всем заранее: пришлите агенду, чтобы люди понимали, о чём разговор, какие вопросы обсуждаем сейчас, а какие отложим.
[34:01] Ещё совет: понимать, когда для разговора хорошее время, а когда нет. Обсуждать техдолг во время релиза — наверное, странно и не стоит. Всегда понимайте, когда тема имеет место быть, а когда стоит повременить. И выбирайте стиль общения заранее: сухой набор фактов — или small talk перед переходом к теме.
[34:34] Дальше совет, который откликается со мной на 100%: сделайте так, чтобы это выглядело нормально — красиво. Презентация должна выглядеть как хорошая презентация. В документации должны быть стилистика, заголовки, структура, абзацы, отсутствие грамматических ошибок. Забавно наблюдать, как разработчики — профессионалы с высшим образованием, которые всё время читают, — пишут тексты, в которых невозможно понять, о чём они. Люди не могут сформулировать мысль: текст выглядит как сплошное полотно букв — ни структуры, ни абзацев. Создают тикеты в джире, в которых просто кусок какой-то непонятной мысли. А если это ещё и ненативный английский — вообще атас. Возможно, за тикетом стоит классная техническая идея и прикольная концепция, но чтобы её понять, она должна быть написана чётко, грамотно и не вызывать банального отторжения. У меня куча примеров: вроде люди прикольные, крутые вещи делают, я бы их послушал — но они не могут говорить, не могут сделать нормальную демку; у них проблемы в простых вещах, которые выглядят смешно на фоне сложности предмета, о котором они рассказывают. Практично: заводите тикет в джире — там есть оформление; сделайте заголовок, опишите мотивацию, используйте списки. Куча простых приёмов делает текст, презентацию, демку приятнее и понятнее. Кстати, в конце будет совет, который поможет прокачаться именно в эту сторону, — слушайте до конца.
[36:56] Дальше: вовлекайте аудиторию как можно раньше. Есть возможность взять ранний фидбэк по документации — попросите кого-то из разработчиков прочитать и сказать, что он думает. Делаете демку — обсудите с кем-нибудь сценарий и ранние недошлифованные версии. Чем раньше вы узнаете, что можно поправить, тем выше вероятность, что поправите. По себе скажу: когда я сделал для митапа записанную и смонтированную демку, потратив очень много времени, весь последующий фидбэк уже не делал погоды — я бы уже ничего не менял. На следующий раз приму к сведению, но текущий вариант не исправлю. А получи я фидбэк до записи и монтажа — можно было бы успеть. Чем раньше обратная связь, тем лучше. Дальше — будьте хорошим слушателем: хотите, чтобы услышали вас, — услышьте других. Понимайте, что люди хотят вам сказать, и говорите, исходя из этого: если говорить только из своего контекста и бэкграунда, люди могут просто не понять. И последний микросовет: всегда отвечайте на сообщения и письма — даже рекрутерам, даже если вам сейчас нерелевантно. Оставлять без ответа — не очень правильная стратегия. Я её придерживаюсь: всегда стараюсь ответить, даже если не знаю ответа — «не знаю», «вернусь к тебе», «добавил в туду-лист, давай обсудим завтра». Довольно эффективная стратегия.
[39:15] Совет этого раздела — один из моих любимых: одинаково важно, что вы говорите и как вы говорите. Это два равнозначных критерия. Доносите суперклассную техническую вещь с банально плохой презентацией — и факт плохой презентации нивелирует всю гениальность идеи. И наоборот: вылизанная красивая презентация, где всё выровнено, но идея ничего не стоит, — тоже без толку. Важно и то, и другое. В конце раздела авторы замечают: документация — тоже часть коммуникации. Комментарии к коду — попытка выразить то, что не получилось выразить кодом; readme, dev notes, комментарии в коммитах (про них я говорил во втором выпуске, если память не изменяет) — всё это имеет значение, и делать это нужно хорошо. Тут я с авторами абсолютно согласен.
[40:47] Вторая часть подкаста посвящена такому слову, как SOLID. Это аббревиатура из первых букв пяти принципов. Первый — single responsibility principle, принцип единственной ответственности. Второй — open-closed principle, принцип открытости-закрытости. Третий — Liskov substitution principle, принцип подстановки Барбары Лисков. Четвёртый — interface segregation principle, принцип разделения интерфейсов. И пятый — dependency inversion principle, принцип инверсии зависимостей. Думаю, большинство моей аудитории так или иначе с ними знакомо и может что-то о них сказать — в первую очередь потому, что эти принципы любят спрашивать на собеседованиях. Но эта часть — не про чистую теорию. Я про то, как я это использую в жизни: действительно ли код, который я произвожу, написан по SOLID? И нужно ли каждый раз писать код по SOLID? Вот на эти вопросы хочу ответить и поразмышлять. Для этого рассмотрим принципы по одному — в целом они собраны вместе просто потому, что собраны: каждый самодостаточен и не требует дополнения.
[42:36] Принцип единственной ответственности говорит: у компонента, юнита, класса должна быть только одна причина для модификации. Это каноническое объяснение. На практике для себя я формулирую так: компонент должен решать одну задачу, делать это хорошо и иметь возможность конфигурирования параметров для её решения. Не две задачи, не три и не четыре — одну, умея подстраиваться. Совет капитанский, и я ему почти всегда следую: он делает код проще для понимания (есть компонент — есть задача, он её решает), проще описывать тесты (тестируем, как компонент решает задачу) и уменьшает связность кода: компоненты меньше знают друг о друге, их проще перемешивать и рефакторить. Принцип единственной ответственности — лайк.
[43:37] Принцип открытости-закрытости — мой любимый. Я использую его почти везде, но неосознанно: пишу код, потом делаю себе селф-ревью и понимаю — кажется, принцип применён, хотя применялся отчасти сам собой. Гласит он следующее: компонент должен быть закрыт для модификации, но открыт для расширения. У меня код так и получается органично: чтобы поменять поведение компонента, внутрь его кода забираться, как правило, не нужно — достаточно дать ему какую-то стороннюю вещь. Например, делаем фильтрацию потока данных: есть класс-фильтр, который принимает на вход поток и возвращает список, и он настраивается правилами фильтрации. Мы можем извне сказать: фильтруй, пожалуйста, по такому правилу — передать лямбду или ещё что-то. Сама фильтрация примитивна. Зачем лезть в фильтр и менять один if на другой, если теперь надо фильтровать поток строк не по наличию буквы, а по наличию трёх пробелов? Правильнее написать код, который принимает правила: кладём извне не правило «фильтровать по букве t», а правило «три пробела и больше» — и фильтр его применяет. Open-closed суперклассный: он даёт возможность почти безграничного расширения вашего кода сторонними программистами и ментейнерами — но никто не лезет внутрь и не изменяет его изнутри, превращая фильтр в набор if-else кейсов или в почти нетестируемую помойку.
[45:51] Принцип подстановки Барбары Лисков: если компонент ожидает интерфейс и определённый контракт поведения — например, чтение файла бросает FileNotFoundException, если файл не найден, — то, подставляя свою реализацию, мы обязаны соблюдать этот контракт. Реализуя интерфейс файл-ридера, мы не можем кидать какой-нибудь runtime error, потому что нам так захотелось: класс-клиент ожидает IOException — его и кидаем. Ожидания использующей стороны должны совпадать с поведением, которое предоставляет реализация. Зачем это нужно? Чтобы можно было вынуть один компонент, подставить другой — и всё работало. По мне, принцип вообще базовый: наследуешь — соблюдай контракт. Всё очевидно.
[46:52] Принцип разделения интерфейсов. К нему я отношусь немного скептически, потому что с ним легко переборщить. Условно, интерфейс «машина» можно представить как что-то, что имеет руль, плюс что-то, что имеет четыре колеса, плюс багажник, капот, двигатель — сделать такую портянку и собрать её в один интерфейс car. В большинстве случаев это перегиб, так делать не надо. Важно соблюдать баланс разумности этой сегрегации. Я бы этот принцип вообще не выносил отдельно — по мне, он из разряда «делай нормально — будет нормально»: делай понятные абстракции и интерфейсы и не собирай всё в одну кучу.
[47:44] И последний — принцип инверсии зависимостей. В Википедии объяснение странное: «всё должно зависеть от абстракций». Если читать «Чистую архитектуру» Роберта Мартина — кстати, именно он сформулировал все эти принципы, — то читается так: код, реализующий высокоуровневую политику, не должен зависеть от кода, реализующего низкоуровневые детали; детали должны зависеть от политики. Перенося на реальность: код не должен знать того, что ему не нужно знать, — не нужно зависеть от деталей имплементации. Пишем генератор отчётов — странно, если он будет принимать URL файловой системы, читать CSV-файлы, парсить их, делать аналитику и генерировать отчёт. Генератор отчёта должен генерировать отчёт; откуда берутся данные, ему знать не нужно. Делаем абстракцию, от которой генератор зависит и которая предоставляет ему данные в универсальном представлении — набор строк, зависит от задачи. А реализация этой абстракции уже знает, что есть файловая система, путь, формат CSV с разделением по табам. Чем хорошо это разделение ролей: деталь реализации всегда можно заменить. В будущем файлы окажутся не в CSV, а в другом формате — или это вообще не файлы, и данные приходят по REST. Все детали получения информации выделены в отдельный класс — его и подменим. А класс, генерирующий отчёт, который знает про формат и бизнес-правила, не поменяется вообще — возможно, это даже другой сервис, и его не придётся передеплоивать. Ещё прелесть разделения: эти части могут разрабатывать разные люди параллельно, не завися друг от друга. По мне, принцип прикольный — но, опять же, не стоит с ним упарываться и вводить абстракцию в каждое место, чтобы никто ни о ком ничего не знал и все общались только через абстракции. Это бред, тут тоже можно перегнуть. Нужна разумность — а где она, эта разумность, каждый раз зависит от ситуации: смотреть и разбираться.
[50:13] На этом пятый выпуск подошёл к концу. С меня, как обычно, рекомендация — и, как я говорил, это будет самая нетехническая рекомендация за всё время. Книга, которая читается быстро и прокачивает один из самых важных навыков — написание текстов. Это «Пиши, сокращай». Обещаю: она не оставит вас равнодушным, как не оставила меня. Ну а на этом всё. Услышимся!