Что можно приобрести, отказавшись от документирования кода функций

Disclaimer: за провокационным названием поста не скрывается призыв оторвать функциональным программистам руки и никогда не писать doc-блоки в коде. Нет. Это сказ о том, что бессознательное следование правилу “описывать поведение функций” не принесёт вам того счастья, которого вы ожидаете.

Все имена вымышлены, все совпадения случайны.

Представьте себе типичный PHP-проект. Jenkins, PHPDocumentor, док-блоки перед каждой функцией с детальным описанием чего она делает, которые потом собираются в единую документацию. Типа круто. Приведу пример знакомого вам с детства оформления кода:

/**
* Функция активации юзера на конкретном сайте.
* Принимает на вход два параметра – идентификатор сайта и емайл юзера.
*
* Помечает сайт как активированный пользователем. Активирует юзера в базе данных. Активирует юзера в биллинге. Отправляет юзеру письмо с логином и паролем. Снимает с сайта гостевой рекламный блок. Подготавливает следующий демонстрационный сайт для прогрева кэша. Записывает в базу отложенных уведомлений пометку, чтобы через неделю отправить юзеру письмо-напоминание.
*
* param $siteId string
* param $email string
*/
function userActivate($siteId, $email) {

}

Знакомо? Так вот, это п***дец.

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

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

И ладно бы, если вы работаете над проектом один. А если вас 5-10 человек, то в будущем каждый будет вносить свой кусочек изменений в исходный код, задействуя одну-две из ваших подфункций для каких-то своих задач. Ну, вы поняли. Через год у вас вырастет Адский Конгломерат v2.0, и вы снова окажетесь в жопе.

Внимательный читатель заметит, что нужно было описать класс User и метод activate, например так:

class User {
public function activate($siteId, $email) { … }
}

Однако, как проницательно замечает один мой коллега, это всё равно что когда вам нужно выкопать яму в земле, вы говорите “земля->копайся()”. Это столь же бессмысленно и вредно, как и “юзер->активируйся()”. Очевидно, что земля не копается сама по себе – её копают. Не объект совершает действие, а над объектом совершается действие.

Как надо делать:

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

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

Не объекты выполняют действия, а над объектами выполняются действия – как реакции на возникающие события. Отсюда возникла и концепция SOA (Сервисно-ориентированная архитектура, продвигаемая IBM ещё с 19xx годов), в которой операции над каждым классом объектов выполняются отдельными изолированными друг от друга сервисами.

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

Во-первых, определитесь с событием. Оно в нашем примере очевидно:

name: user.activate
params:
  siteId: 1234567890
  email: vasya@pupkin.ru

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

Вот его надо документировать, а не ваш код.

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

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

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

Итак, реагируем на событие:

1) Сервис, отвечающий за пользователей, ловит это событие и отмечает пользователя как активированного.

2) Биллинг ловит это событие и начинает считать по пользователю списание средств.

3) Сервис, отвечающий за сайты, активирует сайт и снимает с него рекламный блок.

4) Сервис нотификаций отправляет пользователю приветственное письмо.

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

Преимущества очевидны, даже если вы не читали литературу по event-driven development. Вместо адского конгломерата вы получаете простую систему с низкой связанностью, а значит с низкой стоимостью владения. Легко внести изменения в поведение любого обработчика прямо “на ходу”, не влезая в остальные. Легко добавить новый обработчик, легко убрать, временно отключить, или заменить любой из существующих.

– Ну и что? – скажете вы. – Нужно просто документировать обработчики в каждом сервисе, и всё. Никто не отменяет документирования кода!

А вот и нет.

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

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

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

Поэтому вместо док-блоков, собираемых PHPDocumentor-ом, гораздо важнее иметь описание межсервисного API – описание того, каков перечень и смысл реакций на те или иные события в системе. Поэтому крайне важно, после того как вы потратили несколько месяцев доводя продукт до следующего major release (когда “устаканивается” внутреннее API) – актуализировать его в wiki проекта, чтобы пользоваться в дальнейшей работе.

50 оттенков геморроя: константы и переменные в PHP

Я ненавижу константы в PHP. Когда мне случайно попадается файлик конфигурации проекта, в котором на три страницы перечислены константы с параметрами, мне хочется оторвать руки автору и пришить их в правильное место. Но давайте разберёмся, почему я их так не люблю. Continue reading “50 оттенков геморроя: константы и переменные в PHP”

Почему сотрудники теряют продуктивность: ликбез о свежем воздухе в офисе

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

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

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

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

Кондиционеры – сплит-системы

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

Запомните, что по трубкам “с улицы” в кондиционер идёт только охлаждающая жидкость. Воздух оттуда не поступает.

Открытые окна

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

Вентилляционные решётки в уличных стенах

По смыслу аналогичны приоткрытому окну.

Вентилляционные отверстия в потолке

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

Физика процесса вентилляции

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

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

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

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

Горькая правда

Если у вас нет “дырок” с достаточной пропускной способностью в потолке или около него, вытяжная вентилляция у вас практически не работает.

Если у вас нет притока воздуха взамен “вытянутого”, приточная вентилляция у вас тоже отсутствует. Более того, при этом не будет эффективно работать и вытяжная, не смотря на наличие “дырок”. Автор оставляет вам возможность задуматься, почему.

Если у вас поступающий воздух тянется прямо с улицы, вы дышите выхлопными газами.

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

Медицина требует, чтобы воздух в любом помещении полностью обновлялся 5 раз в час. Каждые 12 минут ваше помещение должно быть полностью очищено и заменено новым объёмом воздуха. Если у вас офис 200 квадратов с высотой 4 метра, то это 800 кубометров воздуха за цикл, или 4000 кубометров в час. У любой профессиональной системы вентилляции такие цифры указаны в основных паспортных данных.

Очистка воздуха

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

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

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

Это один из наиболее эффективных способов мойки, если бы не производительность: в аппарате установлен вентиллятор, по размерам близкий к кулеру процессора. Вспомните про 4000 кубов в час.

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

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

Шум от вентилляции

Мы привыкли, что любой вентиллятор шумит. Однако это не так. Шумят простые и наиболее распространённые вентилляторы, в которых ось и двигатель находятся в центре воздушного потока и имеются лопасти, направленные под углом к нему, которые как-бы “рубят” воздух, вынуждая его двигаться. Пример – любой типичный компьютерный кулер.

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

Также шумит любая щель, практически любой изгиб и изменение диаметра вентилляционной трубы. Когда вы видите узкую решёточку, тонкую щель над “блином” в потолочной вентилляции, или узкую трубу в стене – знайте: это либо практически не работает, либо работает и адски шумит.

Как должно быть на самом деле

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

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

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

Продолжение: Сказ о принудительной приточной вентиляции

Пара слов о построении архитектуры распределённого веб-сервиса

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

Какую производительность CMS считать нормальной?

У каждого веб-мастера, администратора или менеджера проекта регулярно возникает зуд на тему: а достаточно ли быстро открывается мой сайт? Ну он идёт в любой из 100500 бесплатных измерителей скорости, проверяется там, получает значение в N секунд и успокаивается. Но однажды, глубокой ночью, ему в голову начинает лезть навязчивая мысль: а N секунд – это много или мало? Может быть CMS таки тормозит? Continue reading “Какую производительность CMS считать нормальной?”