Pull to refresh

«Пластилиновая» архитектура

Perfect code *
Я думаю, любой руководитель проекта или ведущий программист хотя бы однажды сталкивался с ситуацией, когда код приложения вдруг оказывался совершенно запутанным, непонятным, а люди, его поддерживающие, в ответ на просьбу исправить ошибку или добавить новую функциональность отправлялись «в астрал» на несколько дней, прихватив с собой изрядную долю бюджета и, возвращаясь, предъявляли ещё более запутанный код с исправленной ошибкой, но добавленной парой других.

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

Большинство провальных проектов обладают одной закономерностью. Они абсолютно лишены структуры. Я называю архитектуру таких систем «пластилиновой».


Немного абстракции


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

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

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

И вот, в какой-то момент, появляется задача, которая влияет на несколько составных частей системы. Привычным движением мы лепим очередной комок… Но вдруг осознаём, что у нас перестала работать какая-то совершенно другая функция. Мы исправляем её, налепив очередной кусок, и получаем ошибки ещё в двух. И это – цепная реакция.

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

Несколько причин


Почему такое происходит? Вариантов множество, но наиболее весомыми мне кажутся три из них:

1. Неадекватные временные рамки, в которых выполняется проект.

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

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

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

2. «Плавающая» спецификация

Если начальная спецификация проекта недостаточно детальна, функции описаны расплывчато, а часть функциональности не оговорена вовсе, то такой проект гарантированно оказывается в группе риска по «пластилиновой архитектуре».

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

В результате мы попадаем, фактически, в предыдущий рассмотренный случай – необходимость срочно (проект-то кончается, а финальный платёж, обычно, самый большой) внести большое количество изменений в код при отсутствии времени и бюджета. Дальше – пластилиновый ком начинает расти, появляются ошибки, ещё больше ошибок, лавина ошибок… Как результат — глобальный и затяжной рефакторинг, либо нестабильный продукт.

3. Проект, пущенный на самотёк

Это, вероятно, самый страшный вариант. За программистами никто не следит, действия не согласованны, инспекции кода не проводятся. Руководитель проекта ограничивается тем, что проверяет наличие программистов на рабочем месте и, изредка, бегло просматривает результаты их «креатива». Обычно это происходит, когда надо демонстрировать продукт заказчику.

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

Что делать?


В результате возникает вопрос: как не допустить «пластилиновый» код. Есть много важных вещей, которые нельзя игнорировать:

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

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

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

Но, на самом деле, я могу дать только один совет. На мой взгляд – самый главный: Думать! Думать перед тем, как писать код, думать в процессе его написания и думать даже после того, как код написан. Не начинайте писать код, не продумав архитектуру, если вы — программист. Запретите это своим программистам, если вы — руководитель. И «пластилиновая» архитектура больше не появится в ваших проектах.
Tags:
Hubs:
Total votes 102: ↑93 and ↓9 +84
Views 12K
Comments Comments 124