Грязная архитектура

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

Проблема

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

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

Ну и сроки, да. Они всегда горят. Разработчики стали той собакой, у которой «всё хорошо»:

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

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

Мы всё ещё не уделяем достаточно внимания бизнес‑логике, а упарываемся по модным библиотекам (привет, Реакт!) и фреймворкам (привет, Ангуляр!). И спорим, что лучше, что хуже, на чём приложения моднее.

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

Инструмент не должен вообще ничего вам диктовать

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

Не должно быть никаких «Реакт‑приложений» или «Редакс‑приложений», потому что это инструменты. Реакт должен рисовать пиксели на экране. Редакс должен работать с состоянием. Всё.

А как надо, умник?

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

Бизнес‑правила — скелет, вокруг которого наворачивается мясо

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

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

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

При грамотно спроектированной архитектуре приложения, вы можете выкинуть Реакт и переписать всё за вечер на Вью. И приложение не поломается, потому что интерфейс зависит от бизнес‑правил, а не наоборот.

А как же фигак‑фигак и в продакшен?

Ну да, есть такое. Сроки горят, прототипы нинужны, на тесты нет времени. Плавали, знаем.

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

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

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

Ну и как тогда начать проект?

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

Но за меня на этот вопрос уже ответил Дэн Абрамов в твитере:

Всё зависит от бизнес‑правил. Проектируйте, опираясь на них

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

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

Ссылки

Конспект «Чистой архитектуры»

Дэн Абрамов в твитере

Новые правила деловой переписки. М. Ильяхов, Л. Сарычева

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

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

Основная мысль

Если относиться к адресату уважительно, то и в ответ к вам будут относиться так же.

Книга не про слова, а про правильное отношение к людям

Переписка — это инструмент, им надо уметь пользоваться. Люди — не инструмент, ими пользоваться не надо, им надо помогать. Собеседник будет охотнее отвечать вам, если ему будет приятно читать письмо.

У нас есть цель: получить совет, назначить встречу, договориться о сотрудничестве. Добиться этой цели проще, если получателю будет приятно читать письмо

Так что можно сказать, что книга — о том, как сделать письмо приятным для читателя.

Об уважении к чужому времени

Целая глава посвящена письмам о срочных задачах, и том как о них пишут: «АСАП», «срочно», «нужно вчера» и вот это всё. Людям не нравится получать письма с такими пометками. Но дело не в самих словах, а в скрытом в них отношении к чужому времени.

Раздражает не слово «срочно», раздражает неуважение. …когда к твоему времени относятся как к расходному материалу. Раздражает, что менеджер может подгонять не из‑за срочности, а просто ради забавы… Всё это — неуважение, и всё это раздражает

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

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

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

Не надо рассчитывать на почту, как на экстренный способ связи.

Всё, что в почте, по умолчанию не «горит». Если что‑то и правда «горит», оно не должно быть в почте

Об эмоциях и агрессии в переписке

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

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

В книге схемы «Когда писать письмо» нет, но её можно найти в лекции на ютубе: Когда писать и когда не писать письмо

В работе редко кто‑то вредит специально. Если кажется, что кто‑то ведет себя нехорошо, скорее всего…

Он не козёл, он просто не знает, как правильно

О праве на отказ

Да‑да, пошла песня про Кэмпа, но камон. Люди любят делать добрые дела и помогать другим людям. Мы социальны, и ощущение, что я помог кому‑то приносит удовольствие, а…

Когда мы даём человеку право на отказ, у него появляется больше поводов нам помочь

Особенно важно право на отказ в холодных письмах, где читатель ничего не должен. Он может даже не открывать письма. Задача таких писем — наладить контакт и выйти на связь, а не продать что‑то.

Об удобстве читателя

Быть вежливым — это не про слова, а про намерения. Сделать удобно получателю — значит проделать за него часть работы, снять часть нагрузки.

Это вообще общий принцип любой переписки: когда один человек думает об интересах и удобстве другого. Само по себе механическое повторение формул не помогает — нужно думать, будет ли это удобно нашему конкретному читателю

Про конфликт ваших принципов письма и удобства читателя.

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

О внимательности, границах, переходе на «ты»

О небрежном отношении к имени знаю из опыта — меня постоянно называют Алексеем, не надо так.

Если бы мы могли оставить в этой книге только одно правило, мы бы оставили вот это: внимательно с именем

Переходить на «ты» лучше при личной встрече. Главное, чтобы в переходе не было напряжения, иначе переход не нужен.

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

Гораздо безопаснее писать о том, что мы сами думаем и чувствуем, — а не лезть со своими оценками в душу другому

О манипуляциях и ситуациях «из ряда вон»

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

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

Лучше прямо сказать: «Я понимаю, что ситуация дурная». И дальше строить аргументацию, исходя из этого

Манипуляция — это когда человек втайне хочет чего‑то одного, а давит на оппонента в другом месте, чтобы тот сам сделал нужное

Об этике переписки

Не писать ничего, что нельзя переслать. В претензиях не переходить на личности и оценивать не человека, а работу и результат.

Не писать ничего, что нельзя переслать. Рабочая переписка не подходит для обсуждений за глаза. Всегда есть риск, что письмо получит не тот, кому оно предназначалось

Все претензии должны быть сделаны без переходов на личности, а оценить можно только работу, а не человека или его профессиональные качества

Об откликах на вакансии

Здесь всё снова упирается в человеческие отношения. Если письмо шаблонное и пытается просто закрыть вакансию, то работодатель скорее всего в нём пользы не увидит и не ответит.

У сопроводительного письма нет обязательной формы. Нет требований по формату и объему; необязательно пересказывать биографию… говорить о своей стрессоустойчивости, коммуникабельности, самообучаемости. Относитесь к этому письму не как к священному ритуалу, а как к общению человека с человеком. У одного проблема, у другого — решение. Они хотят договориться

Об ответах на хамские письма

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

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

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

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

О шаге навстречу

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

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

Ссылки

К этой книге:

Мимо пролетало:

Об эффективном делении рабочего времени

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

Зачем делить день на куски

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

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

Разделение дня на куски помогает ведру постоянно наполняться

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

Как бы научная гипотеза, почему так

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

В университетах на БЖД учат что работоспособность зависит от длительности работы. Как видно из графика, работоспособность со временем падает, а после отдыха слегка возрастает.

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

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

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

Подтверждения я нашёл не только в лекциях по БЖД, но ещё и в рассылке Найсэндизи. Меня убедило.

Как делю день я

Рабочий день я делю на блоки по 3–4 часа. Блоков может быть 2, 3 или больше — зависит от загрузки. Если их больше 2, то я снижаю продолжительность последних блоков на час‑полтора.

Между большими блоками я делаю длинные перерывы: ем, меняю место, откуда работаю, просто прогуливаюсь. Обычно хватает 30–60 минут.

Каждый блок я делю на периоды по часу. Периодами удобно измерять задачи и сверяться с планом. В одном блоке получается 2–4 периода, зависит от размера блока.

Каждый период я делю на отрезки по 20–30 минут. Отрезок включает в себя работу и перерыв. Например, отрезок в 30 минут я делю на 20–25 минут работы и 5–10 минут отдыха. Это похоже на помидорки, только я таймер не ставлю.

Иногда я всё‑таки забываюсь, и несколько отрезков сливаются в один без отдыха, тогда в конце периода я отдыхаю дольше.

Минусы

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

Иногда нужно намеренно останавливать работу. Бывает, вхожу в раж и фигачу код как не в себя. Блок заканчивается, а я «хм, может продолжить? прёт же». В это время я себя останавливаю, потому что:

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

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

Плюсы

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

Ведро концентрации наполняется быстрее. Меньше отвлекаюсь во время работы на твитер, чувствую себя менее уставшим после рабочего дня.

Удобно делить день и измерять время, потраченное на задачи. А если запомнить, какая задача сколько заняла времени, получается точнее прогнозировать сроки.

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

Ссылки и материалы

Книги:

Лекции и Википедия:

Рассылки, каналы, инструменты:

Время для чтения есть всегда — 2

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

Большую часть приёмов я взял из лекции Людвига Быстроновского «Дизайн дизайнера». Советую её посмотреть, Людвиг там объясняет причины своих выводов и как к ним пришёл.

Я лишь пробегусь по тому, какие приёмы использую.

Читаю сразу несколько книг

Я не читаю одну книгу за раз, у меня всегда открыто несколько книг. На ноутбуке книги по программированию, на телефоне всё остальное.

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

Так я не устаю от одной и той же книги, и пропадает основная причина лениться: что якобы за книгой нужно куда‑то идти. Не нужно, всё всегда под рукой.

Не читаю неинтересные книги

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

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

Или «Урбанистика» Глазычева — похожа учебник для вузов, написанный академическим языком с предложениями по 3 страницы. Продираться сквозь язык было тяжело, но польза от книги перевешивала.

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

Не парюсь о количестве страниц

Раньше я выставлял себе суточный минимум в страницах. В какой‑то момент я заметил, что он превратился в суточный максимум: прочёл 50 страниц и с чувством выполненного долга закрыл книгу.

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

Читаю в перерыве между подходами в работе

В перерывах, если чувствую, что не сильно устал, читаю.

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

Читаю на досуге

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

Делаю перерывы в чтении

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

Я понимаю, что пора делать перерыв, когда перестаю воспринимать то, что написано.

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

Не читаю, если совсем не прёт

Бывает, что система даёт сбой, и мне не помогают даже перерывы. Когда‑то давно я парился над этим, но сейчас отношусь проще.

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

Копипаста в коде

Копипаста в коде — это не зло, а инструмент.

Не удаляйте дублирование сразу. Дайте ему показать вам, как всё на самом деле работает, и какие паттерны вы ещё не увидели.

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

Обычно я жду 3 повторов, чтобы начать чистить код. А чтобы не потерять места с копипастой, помечаю их коммент‑флагом @DUPLICATE.

После самого флага пишу, какую функциональность он дублирует. Это даёт флагу осмысленное и уникальное имя, по которому потом проще искать места для рефакторинга. Выглядит так:

// @DUPLICATE: solves difficult problem
const someFunc = (a, b) => 
  /* some sophisticated logic */

// @DUPLICATE: solves difficult problem
const duplicatesFunctionality = (a, b) => 
  /* the same sophisticated logic */

Нет, я не против DRY. Я за то, чтобы использовать его с умом.
Да, утверждение холиварное. Сорри, если вдруг заполыхало.

Раньше ↓