Автопрочитывать почту

Я живу без уведомлений, потому что они меня раздражают. Исключения — баджик на иконке почты и Слака (от упоминаний через @ и личных). Если в Слаке по пустякам баджик не появляется, то почта в какой‑то момент начала подбешивать.

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

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

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

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

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

+10 к спокойствию и сосредоточенности.

Джедайские техники. Максим Дорофеев

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

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

Работа с проектами по Дорофееву напомнила мне GTD, но GTD я терпеть не могу, а вот «джедайство» почему‑то зашло. Возможно, потому что Дорофеев описывает, как работают (а точнее мешают нам работать) когнитивные искажения. Возможно, потому что написано простыми словами. Но в любом случае, поехали.

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

Откуда у нас вообще проблемы с эффективностью

Люди решают задачи мозгом, а у мозга куча ограничений. Самое вредное из них — мозг не любит думать. Об этом писал Канеман в книге Думай медленно… решай быстро, на которую Дорофеев также ссылается в тексте.

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

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

…которого конечно же не существует. Вместо него Дорофеев даёт универсальный совет на все времена.

В любой непонятной ситуации — думай

Потому что…

Думать все‑таки придётся

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

Почему эффективность падает

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

Однако, даже если звёзды сошлись, и мы начали решать задачу, это не гарантирует, что мы её решим. Потому что…

По физиологическим причинам нам бесконечно тяжело фокусироваться на одном объекте дольше небольшого промежутка времени

Чем масштабнее и сложнее задача, тем более склонен ее исполнитель к прокрастинации

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

Память, концентрация, настроение — всё это ресурсы, которые мы тратим в течение дня.

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

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

В психологии есть такое понятие, как «повторяющееся торможение» — неизменной информации уделяется все меньше и меньше внимания

Мыслетопливо

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

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

  • принять отсутствие легкого пути;
  • регулярно восстанавливаться;
  • разгружать рабочую память;
  • регулярно очищать инбоксы;
  • не распыляться.

Регулярное восстановление требуется, потому что перенапряжение «умственной мышцы» снижает её удельную работоспособность. Грубо говоря, если фигачить 4 недели в режиме аврала, то к концу вам будет сложно справляться даже с простыми задачами.

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

Практически любое развитие происходит в точке покоя

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

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

Держать инбоксы пустыми тоже полезно, потому что большое количество задач или предстоящей работы оттягивает на себя внимание, заставляет думать о том, как вы будете это решать. (Или «как мало времени у вас на всё».)

Ну и…

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

Откуда берётся тревожность

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

Их можно сравнить с двумя системами мышления по Канеману: решала — это Система 2, основательное медленное мышление, логика, рациональность и всё такое; обезьянка — Система 1, быстро, импульсивно, на эмоциях.

Обезьянка ищет способы «получить удовольствие» и «сделать быстро». Именно из‑за неё человек долго прокрастинирует прежде чем начать работать над задачей. Так вот…

Незавершенные задачи создают стремление их завершить

Если работы очень много, наше естественное (обезьянье) желание — как можно быстрее со всем этим разделаться

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

В дополнение к этому уровень тревоги поднимают уведомления. Отключить уведомления бывает трудно: «вдруг я что‑то пропущу?», «не могу, специфика работы» и проч., но…

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

«Я не замечаю уведомлений» на самом деле стоит понимать как: «Я уже не осознаю, как и в какой степени эти уведомления меня бесят»

Чтобы определить свой уровень тревожности, нужно…

Сесть спокойно, расслабиться, запустить секундомер, закрыть глаза и позволить своим мыслям блуждать, как им заблагорассудится. Как только, по вашим ощущениям, пройдет минута — посмотрите на секундомер: он покажет, сколько реальных астрономических секунд в вашей субъективной минуте. Этот тест — отличный индикатор вашего текущего уровня тревоги. [Если ваша субъективная минута меньше 50 секунд — это проблема, прим.]

Искажения

Кроме тревожности на наше состояние влияют когнитивные искажения. Например…

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

Путаем «сложно» (или «неэффективно») с «невозможно»

Путаем временную последовательность событий с причинно‑следственной связью

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

Ответ на последний вопрос — нет, потому что…

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

Более того, мы толком не умеем планировать, тоже в частности из‑за искажений:

Ещё один неприятный момент, вытекающий из раннего составления планов, — это эффект установки (einstellung effect). Он заключается в том, что наличие у вас какой‑то идеи препятствует появлению лучшей идеи

Сам по себе метод [SMART, прим.], возможно, очень даже полезен… но на практике его применение часто запинается о черту, свойственную живым людям, — избирательность внимания. Дело в том, что чем сильнее мы сосредотачиваемся на каком‑то объекте, тем больше вероятность, что мы упустим все происходящее вокруг этого объекта

Ну и вообще, жизнью правит неопределённость.

Неопределённость

Дорофеев часто отсылает к Талебу — тому самому, который про Чёрных лебедей. Неопределённость не только не даёт предсказать свою будущую производительность, но и мешает планировать проекты.

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

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

Есть способ с этим справляться:

План проекта — это не обязательство, это план. Он может меняться под воздействием обстоятельств

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

Сила воли и контекст

У меня когда‑то щёлкнуло и я перестал полагаться на силу воли, потому что у меня её нет. Я начал создавать вокруг себя такое окружение, чтобы сделать что‑то неправильно было просто «невозможно», или дико неудобно. Дорофеев примерно о том же:

Если вы не можете чего‑то избежать — упорядочьте это

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

Ешьте левой рукой… если вы постоянно ловите себя на том, что делаете что‑то слишком часто, сделайте это занятие менее удобным

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

[Если] исходная задача действительно важна, надо подстраховаться, чтобы после неожиданного отвлечения вспомнить о ней и вернуться к ее выполнению

Используя повторяющиеся задачи, вы можете с легкостью (и без дополнительных усилий) сделать так, чтобы уведомления из соцсетей вы обрабатывали по вторникам и четвергам, а письма из бухгалтерии и уведомления из JIRA — по средам и пятницам. Если не создавать эти периодические задачи и пытаться управлять обработкой этих категорий писем «по памяти», это приведет к дополнительному расходу мыслетоплива

Контекст, в которым вы находитесь, неразрывно связан с неопределённость. Я бы даже сказал, что он (no pun intended) определяется неопределённостью:

У одного и того же человека в течение дня минуты [за которые он или она решит задачу, прим.] будут разными

Указывать расстояние в днях пути без конкретизации способа передвижения уже неуместно

Если вы роете, это не гарантирует вам норку. Но если вы этого не делаете, вам практически гарантировано ее отсутствие

При попытке впихнуть невпихиваемое: 1) выпихивается ранее впихнутое; 2) уменьшается предел впихиваемости

Автор так же говорит, что не существует панацеи против всего этого:

Если сомневаетесь в том, что сможете заставить себя следовать этой (или какой‑либо еще) модели самоорганизации, — не сомневайтесь. Вы гарантированно не сможете себя заставить ей следовать

Но как минимум…

Не надо торопиться с… обещаниями

Не надо требовать от себя раз и навсегда прекратить посещение соцсетей. Именно в этом причина вышеописанной неудачи. Попробуйте добавить в свой список ежедневные повторя­ющиеся задачи вида «провести пятнадцать минут за чтением новостей»

Методология

Закончили с «предпосылками», перейдём и к самой методологии из книги. Всю поступающую информацию мы делим на:

  • задачи;
  • проекты;
  • справочную информацию;
  • встречи.

Самое главное — не перемешивать все эти сущности

Задачи

Задача — это ответ на вопрос «Что нужно сделать». Для задачи очень важна формулировка. Видите ли…

Список задач — это инструмент преимуще­ственно для вашей внутренней обезьянки

Правильная формулировка задач призвана снизить интенсивность мыслительной жвачки

Задачу можно выполнить, по минимуму используя мышление

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

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

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

Может показаться, что писать такие формулировки — долго, но…

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

Чётко поставленные задачки всегда будут побеждать крупное, общее и неконкретное

То же самое с делегированием:

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

Также автор рассказывает о том, как быть с задачами, которые «надо сделать СРОЧНО!!!»:

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

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

…для таких «задач‑ублажителей» он советует применять принцип 20/80. Лучше делать что‑то медленно, чем не делать вовсе.

Кто не роет, у того нет норки

Проекты

Обзор проекта и составление задач по нему сводится к следующему:

  • Подумать над проектом и вычислить ближайшую задачу (сформулированную по всем правилам и понятную вашей обезьяне) по проекту.
  • Записать задачу в список задач.
  • Выполнить задачу.
  • Вернуться к пункту 1.

А вот с планированием уже посложнее, там придётся отвечать на вопросы:

  • Что надо сделать?
  • Чтобы что? (Зачем это делать?)
  • А что ещё? (Что мы пропустили?)
  • А не то? (Что произойдет, если проект не будет выполнен?)
  • И что? (Насколько страшны и суровы последствия невыполнения этого проекта?)
  • Кому и для чего нужны результаты этого проекта­?
  • Как ещё можно достичь «чтобы что»?

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

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

Справочная информация

Самое важное при добавлении новой справочной информации — определиться…

Когда (при каких условиях) этот кусочек мне потребуется? Где я, скорее всего, буду его искать в этот момент? Эти два вопроса — элемент заботы о будущем себе

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

Встречи

Для встреч и отметок о них лучше всего использовать календарь.

Образ жизни

Иногда мы путаем проекты с образом жизни:

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

Для таких штук (в книге этого нет, но) я использую текущую инициативу.

Упарываться в новый образ жизни с головой тоже не стоит. Лучше делать как писал Буров у себя в канале — разбивать «образ жизни» на куски. Смотреть, нравится ли, и после этого принимать решение, продолжать или нет. И не давать обещаний слишком рано.

Чек‑листы

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

Практически любая ситуация, в которой вы хотя бы раз с досадой воскликнули, хлопнув себя по лбу: «В следующий раз, когда я буду делать X, надо обязательно не забыть про Y и Z», тонко вам намекает, что у вас должен быть сформирован чек‑лист для дела X

Помидоры

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

Каждый «помидор» должен состоять из трех основных этапов:

Подготовка к помидору. Просмотрите свой список задач и решите, что вы сделаете в следующие 15–25 минут

Помидор. Поставьте таймер и начните работать

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

Обзоры задач, проектов, системы в целом

Обзоры нужны, чтобы быть «рациональным фланёром» — корректировать план при возникновении новых исходных данных в контексте. Обзоры мы делим на ежедневные, еженедельные и по требованию.

Ежедневные нужны, чтобы спланировать день.

  • Просмотрите запланированные на сегодня, но не выполненные задачи. Надо ли вам в связи с этим что‑то сделать прямо сейчас?
  • Какие задачи вам надо будет выполнить завтра­?
  • Есть ли в вашем списке на сегодня задачи, которые менялись больше суток назад? Переформулируйте их.

Еженедельные — чтобы спланировать (сюрприз) неделю:

  • Запланировали ли вы те задачи, которые вам обязательно нужно выполнить на этой неделе? Просмотрите календарь на неделю‑две вперёд. Надо ли что‑то сделать в связи с увиденным?
  • Все ли задачи в списке всё ещё надо сделать?
  • Просмотрите свой список активных проектов. Есть ли задачи, которые стоит занести в свой список для дальнейшего продвижения проектов вперёд?
  • Все ли проекты в вашем списке проектов всё ещё активны?
  • Просмотрите задачи, завершенные на прошлой неделе. Надо ли (можно ли) еще что‑то сделать?

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

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

Ключевой момент — ограничить время и ни в коем случае не стараться сделать все сразу и идеально

Страхи и «кроме работы»

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

Столько всего не сделано!

В этом случае, как и раньше, вам придётся делать не все

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

Со временем вы научитесь дозировать нагрузку на мозг

В списке задач отсутствуют личные задачи

Самое страшное — не разгребание накопившихся входящих, а отсутствие ответа на вопрос «ради чего мне вообще надо поддерживать порядок

Если у вас нет того, что вы искренне хотите делать для себя лично (если кто‑то другой от этого тоже будет в плюсе — это прекрасно, но в первую очередь дело должно нравиться лично вам), у вас остается единственная цель работать больше и продуктивнее — работать еще больше и продуктивнее

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

Неявные списки задач

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

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

Делегирование будущему себе

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

Нетерпимость к незавершенным делам

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

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

Итого

  • В любой непонятной ситуации — думать.
  • Думать всё‑таки придётся.
  • Регулярно проводить обзоры.
  • Уменьшить вредные переключения.
  • Не доверять силе воли, а менять контекст.
  • Кто не роет, у того нет норки.
  • Главное — не время, а мыслетопливо.
  • Найти любимое дело за пределами офиса.
  • Время и силы, которые удалось «отвоевать» у работы, тратить только на себя.
  • В этом мире не всё везде и всегда, а кое‑что иногда и местами.

Из приложений к книге

  • Не ищите универсальных решений и методов и тем более программ и инструментов.
  • Не старайтесь сразу решить проблему полностью.
  • Доверяйте опыту больше, чем результатам размышлений.
  • Выгружайте содержимое рабочей памяти.
  • Создайте периодическую задачу для обработки старых входящих с формулировкой вида: «Посвятить десять минут обработке входящих из моего старого инбокса».
  • Создайте задачу на еженедельный обзор системы. В описание задачи перенесите соответствующий чек‑лист, за основу возьмите список контрольных вопросов.

Список литературы

Книги:

Посты крутых ребят:

Мои посты:

Википедия:

Компоненты — это организмы

Я достаточно долго пытался сформулировать для себя, что такое «Компонент».

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

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

Компонент, как изолированная сущность

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

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

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

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

ДНК компонентов

Организм развивается под действием ДНК и внешней среды. Компоненты — так же.

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

Давайте на примерах.

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

Кнопка должна уметь показывать, что на неё можно нажать, и по нажатию что‑то произойдёт.

Если компонент не умеет делать то, что «должен», он не нужен — то есть он не выживает.

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

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

Если присмотреться повнимательнее, то видно, что одно из таких «внутренних правил» — это принцип единственной ответственности. Этот принцип (SRP) — часть ДНК компонента, которая составляет часть исходных данных, которые определяют жизненный путь компонента.

Компонент во внешней среде

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

Снова на примерах. Форма поиска — это совокупность компонентов — сообщество:

У каждого организма в этой совокупности есть собственная роль — специализация:

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

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

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

Если же на сайте не осталось форм в принципе, то Текстовое поле как компонент перестаёт быть нужным и вымирает. Это называется эволюция.

Эволюция компонентов

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

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

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

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

Если коротко — компоненты стремятся делать как можно меньше работы, но как можно лучше.

Эволюция среды

Внешняя среда тоже развивается. Сообщества растут или отмирают, условия развития компонентов и сообществ становятся жёстче или ослабевают. Всё это отражается на развитии компонентов.

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

Кнопка — отличный пример. Когда на сайте нет никаких форм кнопка мимикрирует под ссылки — она выглядит как кнопка, нажимается как кнопка, по нажатию что‑то происходит — но это не кнопка.

И это я ещё даже не говорю о компонентах‑паразитах; это, пожалуй, на какой‑нибудь другой раз.

Дизайн‑системы Экосистемы

Компоненты собираются в сообщества; сообщества — в группы; группы сообществ — в экосистемы. Экосистема — набор внешних и внутренних правил, по которым живёт проект.

Например, SRP — часть экосистемы, потому что диктует, как компоненты определяют свою специализацию. Наличие функции поиска на сайте — тоже часть экосистемы, потому что определяет, будет ли существовать, например, Форма поиска. Любое отношение между компонентами (симбиоз, паразитарные отношения) — всё это части экосистемы.

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

Капец ты двинутый

Как ни странно, всё это помогает проектировать системы с учётом таких старых друзей, как например SOLID.

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

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

Ссылки

Не надо заставлять

В эфире рубрика «Лайфаки от капитана Очевидности». Рассказываю, чё делать, если не получается себя заставить чё‑то делать.

— Когда не получается заставить себя чё‑то сделать, не надо заставлять себя это делать.
— Спасибо, Кэп!

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

На примере, пожалуйста

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

Пробовал помидорки, но они не работали. Я откладывал отдых, забивал на перерывы и обнаруживал себя проработавшим 14 часов подряд. А потом пытался понять, чо ж было не так.

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

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

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

Радикально как‑то

Ну да! Но такой способ даёт понять, действительно ли мне так важна эта хрень, которую я не могу заставить себя сделать. Если нет, то ну и зачем она мне?

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

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

Другие о том же

От Редакса к хукам

В Реакте в версии 16.7.0 появились Hooks (дальше по тексту — хуки). Это API, которое позволяет использовать локальный стейт без использования классов. И среди них есть один, который, как мне кажется, может заменить собой Редакс.

В этой статье я предполагаю, что вы знаете разницу между функциональными компонентами и классами, в курсе о локальном стейте и жизненном цикле компонентов и о том, как работает Редакс. Без этого вникнуть будет трудно, но всё в одну статью я бы не уместил, так что вот ¯\_(ツ)_/¯

Что за хуки?

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

Например, здесь мы используем хук useState, чтобы создать и использовать переменную counter:

import React, {useState} from 'react'
const SimpleComponent = () => {
  const [counter, setCounter] = useState(0)
  // в первый раз значение counter будет равно тому, что мы передаём в useState
  // затем — тому, что мы установим через setCounter
  return <div>{counter}</div>
}

useState возвращает кортеж из значения и функции, которая будет это значение обновлять.

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

useReducer

useReducer — это хук, который по принципу работы схож с редьюсерами из Редакса.

const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState)
  // initialState — начальное состояние
  // reducer — функция, которая принимает state и action 
  //           и обрабатывает изменение состояния
  //
  // state — текущее состояние
  // dispatch — функция, которая будет дёргать экшены, 
  //            чтобы обновить состояние

  return <div>Hello world</div>
}

По принципу работы это и есть Редакс. Проблема только в том, что переменные state и dispatch находятся внутри области видимости функции App, а значит использовать этот редьюсер в других компонентах у нас не получится.

…Если только мы не используем контекст.

Context API

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

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

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

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

import {createContext} from 'react'
// создаём контекст
const StoreContext = createContext()

const App = () => (
  // через провайдер в свойстве value указываем значение,
  // которое нам надо хранить и как-то использовать в других компонентах
  <StoreContext.Provider value={{meaningOfLife: 42}}>
    <OtherComponent />
  </StoreContext.Provider>
)

const OtherComponent = () => {
  <StoreContext.Consumer>
    // через консьюмер получаем доступ к значению
    {({meaningOfLife}) => (
      <div>{meaningOfLife}</div>
    )}
  </StoreContext.Consumer>
}

Вызывать консьюмер можно где угодно, и это позволяет делить состояние между компонентами. И тут возникает мысль, нельзя ли заменить Редакс на смесь хуков и контекста. Ну и эт, вроде, можно.

Пример

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

По структуре оно будет состоять из корневого компонента App, компонента формы Form и ещё одного компонента с кнопкой внизу Display. Схематично можно изобразить так:

Компоненты Form и Display зависят от хранилища, в котором содержится состояние приложения. Все события кнопок и инпута вызывают экшены, которые будут обновлять хранилище.

С использованием Редакса

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

// reducers.js
import {combineReducers} from 'redux'

const app = (state, action) => {
  switch(action.type) {
    case 'PLUS':
      return {...state, counter: state.counter + 1}

    case 'MINUS':
      return {...state, counter: state.counter - 1}

    case 'MAGIC':
      return {...state, counter: Math.floor(Math.random() * 100)}

    case 'CHANGE':
      return {...state, counter: +action.value}

    case 'RESET':
      return {...initialState}

    default:
      return state
  }
}

export default combineReducers({ app })

// index.js
import {createStore} from 'redux'
import rootReducer from './reducers'
import App from './App'

// создаём хранилище
const store = createStore(rootReducer)

// используем через провайдер
render(
  <Provider store={store}><App /></Provider>,
  document.getElementById('app'))

Дальше создадим экшены, которые будут вызываться событиями кнопок и инпута:

// actions.js
export const plus = () => ({ type: 'PLUS' })
export const minus = () => ({ type: 'MINUS' })
export const magic = () => ({ type: 'MAGIC' })
export const reset = () => ({ type: 'RESET' })
export const change = e => ({ 
  value: e.target.value,
  type: 'CHANGE', 
})

Чтобы привязать какой‑то компонент к хранилищу, используем connect:

import {connect} from 'react-redux'
import {reset} from './actions'

// app — часть хранилища;
// reset — экшен;
// всё это мы привязали через connect перед экспортом ниже
const Display = ({app, reset}) => {
  const {counter} = app

  return <footer>
    <p>Another component knows that counter equals to {counter} as well!</p>
    <p>
      It even can 
      <button onClick={reset}>reset the coutner</button>
    </p>
  </footer>
}

// мапим свойства из хранилища и экшены
// на пропсы компонента
export default connect(
  state => ({ app: state.app }),
  {reset}
)(Display)

В результате приложение будет работать так.

Контекст + хуки

Теперь напишем то же самое без использования Редакса. Используем useReducer:

// store.js
export const initialState = {counter: 0}

// редьюсер точно такой же, как в прошлый раз 
export const reducer = (state, action) => {
  switch(action.type) {
    // ...
  }
}

// index.js
import {reducer, initialState} from './store'

const App = () => {
  // создаём в корневом компоненте хранилище
  // и функцию для его обновления
  const [state, dispatch] = useReducer(reducer, initialState)
  return <div></div>
}

Чтобы пробросить значения из хранилища компонентам, воспользуемся контекстом:

// context.js
import {createContext} from 'react'
export const StoreContext = createContext()

// index.js
import {reducer, initialState} from './store'
// импортируем созданный контекст
import {StoreContext} from './context'

const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState)

  // используем провайдер, чтобы передать в контекст 
  // хранилище и функцию для обновления
  return (
    <StoreContext.Provider value={{dispatch, state}}>
      <Form />
      <Display />
    </StoreContext.Provider>
  )
}

export default App

Чтобы привязать какой‑то компонент, используем консьюмер:

import React from 'react'
// импортируем контекст 
import {StoreContext} from './context'
// экшены точно такие же, как в прошлый раз
import {reset} from './actions'

const Display = () => (
  // получаем доступ к тому, что хранится в контексте
  <StoreContext.Consumer>
    // в нашем случае — state и dispatch
    {({state, dispatch}) => (
      <footer>
        // используем state, чтобы вывести значение счётчика
        <p>{state.counter}</p>
        // используем dispatch, чтобы дёрнуть экшен
        <button onClick={() => dispatch(reset())}>reset</button>
      </footer>
    )}
  </StoreContext.Consumer>
)

export default Display

А ещё можно сделать код чище, заменив консьюмер на useContext:

import React, {useContext} from 'react'
import {StoreContext} from './context'
import {reset} from './actions'

const Display = () => {
  // вызываем useContext, передавая аргументом нужный контекст
  const {state, dispatch} = useContext(StoreContext)

  return (
    // убираем консьюмер
    <footer>
      <p>{state.counter}</p>
      <button onClick={() => dispatch(reset())}>reset</button>
    </footer>
  )
}

export default Display

И работает оно точно так же.

А чо по весу и перформансу?

Я не удивился, когда бандл ужался на 12 кБ: с Редаксом — 166, без него — 154. Это логично, меньше зависимостей — меньше вес.

А вот прирост в скорости обработки экшенов и отрисовки меня слегка удивил. Я проводил измерения с помощью console.time и performance.measure. Средние значения за 100 итераций вышли такими:

 console.timeperformance.measure
Redux12 мс13 мс
Context + hooks9 мс8 мс

Минусы

Вызов экшенов стал чуть более многословным из‑за прямого использования dispatch. И если работать с контекстом без useContext, придётся использовать паттерн render‑prop, из‑за чего может подняться щит‑сторм ¯\_(ツ)_/¯

Но если серьёзно, хуки — пока что в стадии RFC, и возможно многое поменяется. Поэтому переписывать свои приложения на них не советует даже Дэн Абрамов. То есть это экспериментальная фигня.

Хотя выглядит всё равно заманчиво :–)

Ссылки

Документация

Доклады

Статьи со сравнениями

Измерения перформанса

Исходники и примеры

Раньше