Pull to refresh

Концепция баррикады

Programming *
Tutorial

Каждый программист когда-то давно, в начале своего Пути писал что-то типа вот этого:
double div( double a, double b )
{
	return a / b;
}


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


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

Концепция баррикады предлагает выход из этого положения.

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

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

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

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

И последняя часть концепции — это «внутрибаррикадные» жители. Они и есть тем, ради чего вся эта затея начиналась. Метод, находящийся внутри баррикады может не проверять входные параметры или текущее состояние объекта, к которому он принадлежит! За него это уже гарантированно сделала баррикада. Во всех внутрибаррикадных методах обязаны стоять ASSERTы, поскольку невалидность чего-нибудь является уже не проблемой взаимодействия с внешней средой, а конкретной ошибкой в баррикаде. Её в дебаг-версии нужно обнаружить и исправить. А в релизе ASSERTы будут выброшены компилятором и не будут никому мешать.

Конечно, в баррикадах есть недостатки — нужно чётко разграничивать вещи относительно баррикады по уровням доверия к ним, проверки внутри баррикады все-равно иногда нужны (ASSERTы), хоть их и значительно меньше. Всё это решает где-то полторы-две из трех описанных в начале статьи проблем, так что иногда может пригодиться.
Tags:
Hubs:
Total votes 134: ↑111 and ↓23 +88
Views 1.4K
Comments Comments 98