Главная » Хабрахабр » Ctrl-Alt-Del: учимся любить легаси-код

Ctrl-Alt-Del: учимся любить легаси-код

Как быть, когда приходишь в большой проект и сталкиваешься с пропастью непонятного старого кода? Какое отношение к легаси-коду имеют «Звёздные войны», группа «Тату» и сочетание «Ctrl-Alt-Del»? И как эффективнее донести до начальства, что трудозатраты на ликвидацию технического долга оправдывают себя?

Такое хорошо подходит для завершения конференции: когда зрители уже услышали много хардкора и больше не могут воспринимать слайды с кодом, самое время для более общих вопросов и яркой подачи. Доклады Дилана Битти не обходятся без шуток, но эти шутки сопровождают вполне серьёзные рассуждения о главных вопросах разработки. NET-конференцию DotNext 2018 Moscow завершало выступление Дилана про легаси-код, зрителям оно понравилось сильнее всего. И когда нашу .

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

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

Я начал разрабатывать веб-сайты ещё в 1992-м, по меркам нашей отрасли — в доисторические времена. Вначале скажу пару слов о себе. Начал там работать в этом году, тем самым унаследовав кодовую базу: моей ответственностью стали 75 тысяч строк кода, написанного не мной. Сейчас я CTO лондонской компании SkillsMatter. Кроме того, я Microsoft MVP и руководитель лондонской юзер-группы . Отчасти мой доклад основан на этом опыте. NET.

При работе над ними был использован легаси-код. Что общего у «Доктора Кто», современных «Звёздных войн», «Шерлока» и «Пэддингтона»? Это лондонская компания, которая предоставляет онлайн-инструмент для профессиональных актёров, снимающихся в фильмах и на телевидении. Мне это известно, поскольку в течение 15 лет я работал в Spotlight. Софт, написанный мной и моей командой, использовался в работе над всеми упомянутыми проектами и многими другими.

Но никто не вышел из кинотеатра со словами «мне не нравится, что при создании был использован классический ASP»! В новых «Звёздных войнах» кому-то не понравились актёры, другим не понравился сюжет.

Эта кодовая база в продакшне очень давно, и да, там присутствует классический ASP — код, который старше, чем весь . Потому что это не имеет никакого значения. Надо правильно ставить акценты: важны именно эти фильмы и сериалы, а код существует только для того, чтобы решать проблемы. NET — который по-прежнему используется сегодня в кастинге для фильмов и сериалов. Ценность у него возникает только тогда, когда вы его запускаете, и с его помощью что-то делаете. Пока вы его не запустили, код сам по себе ничего не значит. Проблема в том, что об этом очень легко забыть. Вот за что люди платят — за Netflix или DVD.

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

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

А этой модели всего 11 лет, она появилась в 2007 году, и стоила она тогда 800 долларов. Взгляните на самый первый iPhone — сегодня он выглядит совершенно древним и громоздким. А вот первый iPhone уже не работает — даже если вам удастся найти экземпляр с батареей и зарядником, в нём не будет работать все те вещи, которые сделали смартфон таким удивительным устройством. Если бы в 2007 году вы купили стиральную машину, гитару или велосипед, сегодня вы по-прежнему могли бы ими пользоваться.

Вы не сможете выйти в Twitter, поскольку последние версии приложения Twitter требуют версии iOS, которую нельзя установить на iPhone 1. Вы не сможете открыть карту, поскольку сервера карт больше не существуют. В сущности, у вас в руках будет ископаемое. Клиент Twitter просто ответит вам: «endpoint not found». Потому что в этой области, в отличие от IT, стандарты за 11 лет не поменялись. А единственное, что в нём будет работать — это функция обычного телефона, по нему всё ещё можно звонить.

Помните вот это? Давайте совершим небольшое путешествие во времени.

«Тату» выступали на «Евровидении» в 2003-м. А помните, в каком году это было? А я в 2003-м писал ASP-код, который сейчас по-прежнему используется в продакшне.

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

Вот пример кода: И хотя мы все согласны, что легаси существует, остаётся вопрос: что именно является им?

Как вы считаете? Посмотрите, подумайте: это легаси или нет?

Вы вставляете его в USB-разъём, выделяете кусок кода, и прибор говорит вам, это легаси или нет! Я изобрёл устройство, хочу в следующем году продавать.

Его написал Андрей Акиньшин (DreamWalker) четыре дня назад. Тот код, который вы только что видели — не легаси. Это взято из BenchmarkDotNet.

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

Мы такие: «ну окей». Если открыть статью «Legacy code» в англоязычной Википедии, то там можно прочитать следующее: «Это исходный код, относящийся к операционной системе или какой-либо иной компьютерной технологии, поддержка или производство которой прекращены». А дальше написано: «Этот термин был впервые использован Джорджем Оливетти применительно к коду, поддержкой которого занимался администратор, сам этот код не писавший».

Мы думаем: «Интересно, посмотрим». В конце этого предложения находится ссылка на блог некоего Самюэля Маллена. Но если мы откроем пост, то увидим, что этот Маллен, в свою очередь, ссылается на Википедию!

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

А Майкл по этому вопросу написал целую книгу, так что он определённо знает, о чём говорит. Одно из самых популярных определений в индустрии дал Майкл Фэзерс: «Легаси — это попросту код без тестов». Но всё же я не до конца согласен с его определением.

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

Мне интересно, откуда берётся этот страх. Позже оказалось, что очень похожее определение уже давали независимо от меня: «очень прибыльный код, который мы боимся менять». Что есть такого в тестах, что превращает код без них в легаси?

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

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

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

Разработчик смотрит на простую строчку кода, и в голове тут же начинает думать о том, что нужно теперь переписать в меню навигации, как это повлияет на отладчик, что затем надо будет поменять в коде. Вспоминается одностраничный комикс «This is why you shouldn't interrupt a programmer». Кто-то подходит к нему и спрашивает: «ты получил моё письмо?», и тут же всё это сложное дерево правок вылетает из головы.

Когда код пишет один человек (например, в стартапе или опенсорсном проекте), зачастую, кроме модели в голове и модели в коде, ничего нет. Когда мы работаем, мы входим в изменённое состояние сознания, наш мозг строит сложные модели, объясняющие работу кода. Правильной является та модель, которая в голове, так что если в коде что-то не так, достаточно взглянуть на него, сравнить с тем, что в голове, и ошибка сразу будет видна. Это позволяет работать очень быстро — вы просто транслируете то, что у вас в голове, в код. А когда вы находите баг, зачастую это показывает вам, что вы какой-то аспект недостаточно продумали, и вы обновляете вначале модель в голове, а потом код.

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

Я был этим человеком в Spotlight — в одиночку написал значительную часть первой версии, причём написал на классическом ASP, без документации и без юнит-тестов. Поэтому во многих организациях можно наблюдать явление, которое Альберто Брандолини назвал «хозяин подземелья» (dungeon master): это человек, написавший первую версию системы. Но затем мы начали нанимать новых сотрудников, которые поначалу не могли разобраться, как это всё работает, и в течение двух-трёх месяцев им приходилось знакомиться с системой. С этим инструментом стали снимать фильмы, сделали «Звёздные войны», у нас появились деньги и всё было замечательно.

NET, поскольку классический ASP недостаточно надёжный и недостаточно быстрый. Вскоре начались разговоры о том, что нужно портировать систему на . Происходит это потому, что этот человек не понимает ваш код, а новый код писать интереснее, чем вникать в старый. Такие разговоры будут всегда — какой бы код вы ни написали, кто-нибудь обязательно будет настаивать, что его надо переписать. Поэтому вполне естественно, что, будучи представлены перед выбором, мы будем склоняться в пользу того варианта, который более увлекательный. Программирование — такая работа, которая приносит удовольствие, нам она очень нравится.

Он знает про ту кнопку, на которую нельзя нажимать, иначе приложение упадёт; ту самую, на которой висит TODO из 2014 года, до которого ни у кого не дошли руки. Хозяин подземелья — это человек, который знает все подводные камни в коде. Это то, за что я люблю мероприятия вроде DotNext, юзер-группы, сообщества и StackOverflow: когда вы начинаете новый проект, вам обязательно объяснят, что нужно писать тесты, делать specification by example, интеграции, мониторинг. Мы в нашей отрасли научились больше не создавать таких систем. Так что наше будущее — это бессерверные микросервисы на F# со стопроцентным покрытием кода тестами.

И, если представить этот софт в виде пирамиды, то бессерверный F# будет занимать лишь самую вершину. Но проблема не в том софте, который нам предстоит написать: в нашем мире уже полно софта. NET, кое-как покрытого тестами. Чуть больше будет ASP. Но самая популярная в истории платформа для разработки коммерческих продуктов — таблицы Excel. Ещё больше — Visual Basic на Windows XP.

Разработка через тестирование не принимает во внимание этот огромный багаж уже написанного кода. Я готов биться об заклад, что каждый раз, когда вы покупаете билет на самолёт или останавливаетесь в отеле, так или иначе ваше имя оказывается в какой-нибудь таблице Excel.

Вначале людям не нравится классический ASP и они хотят переписать всё на . Но почему нужно настаивать на том, чтобы переписывать старый код? Потом выясняется, что нужно всё переписать на версии 4. NET. 6, потом . 5, потом 4. JQuery никуда не годится, поэтому нужно обязательно перейти на Angular, после чего настанет очередь React, затем Vue. NET Core.

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

Представьте, что перед вами лежит два резюме:

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

Некоторые из моих коллег ушли из нашей команды потому, что они хотели работать на Angular или на NodeJS. Я думаю, одна из причин такого отношения в том, что людям страшно. NET, то через два года не смогут найти работу. Когда я спросил их, зачем им это нужно, они ответили, что если они будут продолжать работать только на . NET только что помогли сделать «Звёздные войны»! Я отвечаю им: ребята, мы со своим . А они говорят: да, но это всё равно не Angular.

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

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

Как нам работать со своим страхом и со страхом наших коллег? Как мы знаем из тех же «Звёздных войн», страх ведёт к злости, злость ведёт к ненависти, ненависть ведёт к страданиям, страдания ведут к JavaScript. На мой взгляд, здесь три основных аспекта: понимание, доверие и контроль.

Я доверяю этому ноутбуку, потому что он ещё ни разу не крэшнулся во время презентации. Доверие — одновременно самое простое и самое сложное из этих трёх. В английском языке есть поговорка «доверие завоёвывают по каплям, а теряют вёдрами». Как только это произойдёт, моё доверие к нему исчезнет. А через три месяца и один день в его коде обнаружится уязвимость к SQL-инъекциям, и вы скажете «А, я всегда говорил, что от него никакого толка». После месяца работы с человеком вы будете готовы признать, что он, возможно, разбирается в своём деле, через два вы скажете, что он разбирается неплохо, через три вы согласитесь, что он знает своё дело очень хорошо.

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

Правда, доверие транзитивно: если я доверяю вам, а вы доверяете кому-то другому, то, скорее всего, я этому человеку тоже могу доверять. Нет быстрого способа добиться доверия. Но быстрого способа добиться доверия нет. Если я прислушиваюсь к вашему мнению, а вы считаете, что можно доверять Amazon, AWS, Azure или Google App Engine, то я буду готов поверить, что это хорошие сервисы.

В университете я три года изучал computer science. Давайте перейдём к пониманию. Если бы принципу, лежащему в основе нашего образования, следовали инженеры-строители, то на первом курсе они строили бы деревянные сараи, на втором — металлические, а на третьем, продвинутом — стеклянные.

Больших программ мы не писали, и, что ещё более важно, не пытались в них разобраться. Мы на первом курсе писали маленькие программы на Lisp, на втором — маленькие программы на Java, на третьем — маленькие программы на Scheme и Prolog.

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

Значительная часть существующего сейчас софта примерно так и была написана. Именно в таком положении оказывается студент, закончивший курс computer science, и получивший задание написать распределённую коммерческую систему закупок. У них очень хорошо получалось всё, что они делали в университете, и это создавало ложную уверенность в себе. Люди, которые его писали, были не безответственными, а просто неопытными. Мы действовали так: напишем веб-страницу, сделаем ссылку на ещё одну страницу, потом ещё одну, скопируем код и все будут рады — у клиентов продукт, у компании деньги, у нас премия. Именно таким в своё время был я, и, я уверен, такими же в своё время были многие из вас. А через пять лет смотришь на этот кошмар и думаешь: как можно было такое написать?

Инженеры-строители хорошо умеют изучать здания, авиаинженеры хорошо умеют изучать самолёты. Проблема отчасти в умении изучать софт. Это одна из самых больших книг в мире, она требует очень серьёзного изучения со стороны людей, которые занимаются литературоведением. Возьмём литературу: в «Войне и мире» может быть 45 тысяч строк (в зависимости от издания). Размер самой длинной пьесы Шекспира, «Гамлета» — 6 тысяч строк. Другими словами, изучение такого крупного объекта — это работа. Причём речь идёт о весьма компактном коде, хорошо организованном, с обширной документацией и многочисленным сообществом. А теперь подумайте: ядро Linux в три раза длиннее «Войны и мира». И тем не менее разобраться в нём аналогично тому, чтобы трижды разобраться в «Войне и мире».

Посмотрите на этот график, на котором показано количество строк в книгах «Гамлет», «Моби Дик», «Братья Карамазовы», «Властелин Колец», «Атлант расправил плечи» и «Война и мир», а также в ядрах Linux и Mono.

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

А линейный график на следующем слайде:

Попросить кого-то познакомиться с ядром Linux аналогично тому, чтобы попросить человека прочитать «Войну и Мир», «Атлант расправил плечи», «Властелина колец» и всех «Гарри Поттеров» подряд. Мысль здесь очень простая: софт огромен, просто сесть и прочитать его невозможно. Конечно же, так не делают. Представьте, что вы пришли в новую компанию, и вам с порога говорят, что надо изучить все эти книги, и только тогда вас не допустят к коду.

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

Вспомним Ричарда Фейнмана, нобелевского лауреата по физике. Если просто читать код неэффективно, то как правильно его изучать? Он считал, что нужно учить людей не науке, а тому, как правильно заниматься наукой. Для него огромную важность имел вопрос преподавания науки. Фейнмана попросили помочь разобраться, в чём проблема. Его пригласили в университет Сан-Паулу в Бразилии, потому что в Бразилии студенты получали очень высокие оценки, но при этом наладить наукоёмкое производство никак не получалось.

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

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

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

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

Чтобы его проверить, вы ставите эксперимент. Далее на основе гипотезы вы формулируете предсказание. А затем сообщаете их своей команде или, если это опенсорсный проект, сообществу. Результаты этого эксперимента вы анализируете.

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

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

Но закончилось всё хорошо — ошибка была настолько несуразной, что на нас никто не подумал, пользователи сочли, что проблема на их стороне. Я как-то раз случайно заменил целый работающий сайт на одну страницу с надписью «I love LAMP», потому что думал, что у меня есть предохранитель при развёртывании, а он не сработал. Мораль проста: если вы сломали систему, то чем масштабнее, тем лучше, тогда на вас не подумают.

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

Компилируется ли он? Следующий вопрос — можете ли вы собрать этот код? Такую ситуацию надо исправить, нужно добиться, чтобы код можно было собрать локально. Иногда код можно собрать только на билд-сервере, «мы просто что-то меняем и отправляем туда». На коде в продакшне можно ставить очень интересные наблюдения, если запустить его, выключив Wi-Fi. Затем собранный код необходимо запустить, и посмотреть, где он упадёт. Дальше вы начинаете изучать ошибки: например, система упала, потому что не смогла найти базу данных — тогда как мне запустить её с базой данных? Без Wi-Fi ничего страшного, скорее всего, не произойдёт, потому что вы не общаетесь ни с какими внешними зависимостями. И так далее.

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

Например, я вижу, что нечто из моего DLL обращается к api.payments.mycompany.com. Это позволяло мне наблюдать все сетевые взаимодействия, чтобы затем создавать стабы. И в этом заключается первый шаг: вам нужно добиться контроля над кодом. Я не могу ничего поменять в самом DLL, но я контролирую среду, в которой работает софт, переменные, то, к чему этот DLL подключается, входящий и исходящий трафик.

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

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

Нам потребовалось два года, чтобы процесс развёртывания кода с GitHub в продакшне стал выполняться без каких-либо ручных «сдержек и противовесов». Мы опробовали этот подход в Spotlight, когда с классического ASP на наших серверах мы решили перейти на Amazon Web Services. Зачастую у людей опускаются руки после двух дней, и они возвращаются к прежней системе, поэтому нужно здраво оценивать количество труда, необходимое, чтобы добиться автоматизации.

В Windows 2016 года достаточно поставить один флаг, чтобы включить поддержку классического ASP, который перестали поддерживать в 2003 году. Интересная особенность легаси-систем в том, что зачастую чем они старше, тем лучше их поддержка.

А вот код на ASP. Иначе говоря, код, который я написал, когда «Тату» выступали на Евровидении, будет работать «из коробки» на Windows 2016 без флагов компилятора, зависимостей или изменений. DLL, которые нужны, чтобы собрать проекты на ASP. NET MVC 2 так не заработает, поскольку это был передовой на тот момент продукт, который очень быстро перешёл на версию 3, а затем 4. Они ищут зависимости в Program Files. NET MVC 2, по-прежнему лежат где-то на microsoft.com, но в тех проектах, которые есть у нас, не используется Nuget для зависимостей, потому что они были написаны до его появления. NET MVC 2, пока не поняли, в чём же дело. Мы пару недель пытались запустить код на ASP.

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

А теперь взгляните на фото: знает ли человек, который сделал вот это устройство, как устроен стоп-сигнал?

В этом примере именно исправный стоп-сигнал — легаси-система, потому что её оператор не знает, как она устроена. Я думаю, он хорошо разбирается в том, как работает эта система, потому что она у него постоянно ломается, и ему приходится заниматься её поддержкой. Сами посмотрите, её поддерживает изолента! А собранный на коленке выключатель — активно поддерживаемая система.

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

Поначалу у нас было 50 000 потенциальных адресатов, и система каждый раз искала среди них подходящих и отправляла уведомления. В нашей компании был прекрасный пример такой ситуации с системой, которая при размещении актёрских вакансий генерировала персонализированные уведомления для подходящих кандидатов. Поняли мы, что произошло, только когда кто-то заметил id в два миллиарда с чем-то. Позже количество возможных адресатов росло — 100 000, 200 000… В общем, спустя четыре с половиной года у нас произошло переполнение Int32. Здесь интересно, что база данных-то поддерживала такие числа, но вот в коде, отправлявшем сообщения, использовался int, и у него происходило переполнение.

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

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

Сотрудники из отделов продаж и консультанты создавали у людей впечатление, что можно всё автоматизировать и уволить всех сотрудников. Одна из причин возникновения всех этих трудностей заключается в том, что в 80-е и 90-е, когда создавались многие из этих легаси-систем, мы активно убеждали всех остальных людей в том, что раз и навсегда решим все их проблемы. Мы продавали идею того, что продукт можно завершить.

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

Когда люди делают работу привычным образом, то есть вручную, они обладают значительной степенью гибкости. При этом мы часто продавали системы, которые реализовали лишь один режим функционирования бизнеса. А когда вместо живого человека постоялец общается системой автоматической регистрации, у него нет возможности сообщить ей о своей проблеме — специальной кнопки «не подавать грибы» в системе нет. Если постоялец отеля говорит, что у него аллергия на грибы, сотрудник просто запишет эту информацию на бумажке и отправит её на кухню. Тогда в администрации думают: «Может, постоялец один раз всё-таки может покушать грибы?» Постоялец в конечном итоге обратится к администрации, а там выясняется, что нужно сделать запрос на изменение, который будет стоить пять тысяч долларов.

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

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

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

Что является нашим «definition of done»? Наконец, давайте ответим на вопрос — какой проект можно считать завершённым?

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

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

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

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

Я уверен, что среди вас множество людей, которые пишут потрясающие новые прогрессивные системы, но я также уверен, что среди вас полно тех, кто занимается, например, интеграцией с банковскими системами на COBOL. Наш мир работает на легаси-коде. Ах, счастливчики. В зале никто не имел дела с MUMPS? Если хотите много заработать программистом в США — учите его. Это худший в мире язык программирования, он был создан в 1960-е годы, до сих пор используется в 26 крупнейших госпиталях в США. Он ужасен, его знание очень высоко оплачивается, и здоровье миллионов людей в США по-прежнему зависит от такого рода софта.

Нам нужно научиться разбираться в унаследованном коде и становиться его владельцами. Легаси-код очень важен, и нельзя просто «добавить юнит-тесты» или «заменить на микросервисы».

И отсюда название моего доклада: нам надо научиться контролировать (control), изменять (alter) и удалять (delete) легаси-код.

Спасибо за внимание.

Там будет много конкретики по . Если вы дотнетчик, обратите внимание: следующий DotNext состоится 15-16 мая в Петербурге. NET Foundation. NET-разработке (для примера можете посмотреть топ-10 предыдущей конференции), и некоторые спикеры уже известны — например, Джон Гэллоуэй из . Увидеть всю актуальную информацию можно на сайте конференции, приобрести билеты там же — и со временем они дорожают.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Ложные срабатывания в PVS-Studio: как глубока кроличья нора

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

Онлайн контест по решению задачи из теории игр

Привет, Хабр! На факультативе по теории игр мы решаем различные интересные задачи, и я хотел бы поделиться с вами одной из таких. Меня зовут Миша, и я студент. Описание игры «Я люблю вархаммер, поэтому решил адаптировать условие» Играют двое. 1. ...