Представьте: у вас родилась идея разработать что-то совершенно новое и решить проблему, которую раньше никто не мог решить. На основе этой идеи вы хотите создать продукт и выйти с ним на рынок. О чем вы будете думать в первую очередь? О том, как бы сделать рабочие алгоритмы и как сделать их максимально быстро!

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

Что такое архитектура?

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

Когда в 2008 году мы начинали писать Macroscop, слово «архитектура» вообще не звучало. И спустя год, и два… На тот момент главной нашей задачей было реализовать идеи, которые мы считали прорывными, вывести их на рынок и получить оценку. Одни идеи воплощались, на их смену приходили новые, на которые мы вновь бросали все силы, и так в режиме нон-стоп.
А разработка при продумывании наиболее оптимальной архитектуры требует много ресурсов, много времени и много сил, которые необходимо потратить на анализ того, как та или иная новая функция повлияет на то, что есть сейчас, как она будет развиваться в будущем, куда продукт в целом пойдет дальше и в каком направлении будет наращиваться функционал. Когда вы находитесь в самом начале пути, когда у вас есть уникальная идея, которую надо во что бы то не стало реализовать и реализовать быстро, все эти время- и трудозатраты – непозволительная роскошь.

Например, у нас появилась идея разработать индексатор (см. статью «Разработка в собственном соку или как мы поняли, что занимаемся не тем, что нужно пользователям»), которого не было больше ни в одном программном продукте для видеонаблюдения. Это была наша цель! Цель – разработать и проверить технологию и как можно быстрее. В тот момент мы не думали, как все пойдет дальше, как эта функция будет развиваться, с какой точки зрения будет наращиваться. Да мы вообще не знали, получится ли у нас что-то из этой идеи или нет. Точно также мы не знали и не предполагали, что в дальнейшем на базе этого индексатора создадим межкамерный трекинг. Мы просто писали функцию так, чтобы она работала, не задумываясь о том, как она впишется в существующий продукт и куда пойдет дальше.

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

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

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

Все это приводило к катастрофическому увеличению времени выпуска новых версий продукта.

С чего мы начали работу над архитектурой

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

image
Источник фото: hsl.guru

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

Очевидно, что с этим надо было что-то делать.

У нас было два варианта решения проблемы:

1. Разбираться в том, что написали и распутывать «паутину».
2. Переписать продукт с нуля.

Мы решили не переписывать Macroscop, а пойти по пути изменения того, что есть, и рефакторить (проводить преобразования кода без изменения его функционала).

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

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

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

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

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

Что же в итоге важнее?

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

Несмотря на то, что разбираться в той паутине, которую мы написали в свое время, сегодня очень сложно и времязатратно, мы уверены, что приняли верное решение, когда в начале своей работы бросали все силы на достижение результата, не задаваясь вопросом «как написать?». Когда ты начинаешь и пробуешь, надо быстро найти точки, в которых ты сможешь стать лучшим. Самое важное – не затягивать с принятием решения приводить архитектуру в порядок. Когда компания вышла на рынок и закрепилась на нем, пора заглядывать в код и решать, что с ним делать, как улучшать, и что будет дальше.
Поделиться с друзьями
-->

Комментарии (7)


  1. apelserg
    30.01.2017 16:28
    +1

    Тема затронута важная и интересная, но, по-моему, совсем не раскрыта.
    Для затравки, было бы не плохо рассмотреть конкретный пример — было так — стало так.
    И рассказать, что удалось исправить, с привлечением каких ресурсов, в чём были изначальные ошибки. Прикрепить схемку (вместо фото паучка).


  1. Varkus
    30.01.2017 16:39
    -4

    Однажды установил Ваш продукт: хм, с#, тогда понятно почему все так.
    И удалил эту программу. Ничего личного.


    1. segment
      30.01.2017 17:49

      А что с C# не так?


      1. Varkus
        30.01.2017 18:55

        1) Да хотя бы то, что его адепты тихо минусуют, даже не потрудившись объясниться.

        2) 100500 раз уже озвучивал: скачайте еще 300 метров этого ванильного фреймворка.

        3) очень субъективно: для меня С# сродни Паскаля и делфистудии, т.е. очень простой вход в программирование для студентов, отсюда и (как написано в статье) — совершенно неструктурированная мешанина кода.

        4) wine app.exe ПРОТИВ 30 минут натягивания .net on wine начиная с версии 2.0 до 4.0(при том что 3.5sp1 не ставится если стоит 2.0) и всё равно в.нет приложении не всё работает. Чувствуете разницу?

        За что я должен любить С#?

        Аргументов масса, но кому они здесь нужны, чувствую после этого коммента и так заминусуют до read-only.


    1. vyatsek
      30.01.2017 18:34

      C# на клиенте или на сервере? и почему негативное отношение именно к инструменту?


  1. http3
    30.01.2017 17:56

    50% времени разработчиков тратится не на разработку нового функционала, а на придумывание, как встроить что-то новое в ту совершенно неструктурированную мешанину кода

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


  1. HedgeSky
    30.01.2017 19:20

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

    Пользователям Хабра объясняют, что такое тесты, серьёзно?