На The Wired не так давно вышла неплохая статья с размышлениями о роли спецификаций в разработке. Тема, несомненно, давно известная, но очередной взгляд на нее наводит на дополнительные размышления, к которым можно добавить и толику адаптации под местные условия.
Примечание редактора оригинала: C распространением онлайновых курсов и всевозможных инструментов, связанных с программированием, «программирование» стало чем-то вроде «писательства» – кто им только ни владеет. Поэтому мы обратились к Лесли Лэмпорту, обладателю медали Джона фон Неймана (престижная награда, вручаемая институтом IEEE), эксперту по распределенным системам. Мы спросили Лэмпорта, что значит, с его точки зрения, выражение «писать код».
Архитекторы-зодчие готовят подробные чертежи здания задолго до того, как будет заложен первый камень или забит первый гвоздь. Архитекторы-программисты так не делают. Не поэтому ли дома рушатся гораздо реже, чем отказывают программы?
Чертежи позволяют архитектору не только рассчитать конструкцию и быть уверенным, что задуманная конструкция будет работать. И «работать» – это не просто «устоять», а служить по назначению сколь необходимо долгий срок. Архитекторы и их клиенты работают с чертежами в том числе и для того, чтобы еще до начала строительства понять, что же они хотят видеть в итоге и насколько это реально.
И если для архитекторов-зодчих создание чертежа – норма, то среди программистов мало найдется тех, кто удосуживается сделать хотя бы примерный набросок подготавливаемой программы. Обычно работа сразу начинается с написания кода. Средний программист считает напрасной тратой времени любую работу, не связанную с написанием кода. Раздумывая, много кода не напишешь, считают они; но если писать код бездумно – он непременно получится плохим. Ведь прежде чем приступать к написанию какого-либо кода, нужно четко представлять, как он должен функционировать. И чтобы понять, нужно думать. А думать сложно. Но, как говаривал иллюстратор ДикГиндон: «Письмо отлично помогает понять, насколько беспорядочны ваши мысли».
Чертежи помогают снизить беспорядочность и четко представлять, что мы строим; прежде чем написать фрагмент кода, сделайте его «чертеж». Аналогом чертежа в программировании является спецификация.
Выдвигается масса аргументов в пользу того, что написание спецификаций для программ – это трата времени. Например, «спецификации бесполезны, кода ведь в них нет». Но попробуйте сказать архитектору, что он зря готовит чертежи, еще не найдя бригаду строителей. Другие аргументы против написания спецификаций также легко развенчать, сравнивая спецификации с чертежами. Впрочем, некоторые программисты считают, что аналогия между спецификациями и чертежами ошибочна, ведь чертежи – не здания. Они считают, что снести стены сложно, а вот изменить код – проще простого. Поэтому якобы можно обойтись без «чертежей» для программ.
Специально для них говорю: а вот и нет! Изменять код сложно, особенно если мы не хотим нашпиговать его багами. В качестве примера приведу ситуацию: недавно мне довелось менять код, написанный не мной, чтобы добавить в программу крошечную функцию. Для этого необходимо понимать интерфейс. Я целый день провозился с отладчиком, чтобы выудить нужную мне информацию – тогда как, имея под рукой спецификацию, потратил бы на это всего несколько минут. Чтобы не наплодить багов, приходилось реконструировать последствия всех изменений, которые я вносил, а без спецификации делать это очень сложно. У меня не было никакого желания искать и прочитывать тысячи строк кода, которые могли бы быть затронуты изменениями – поэтому я тратил целые дни, чтобы свести такие изменения к минимуму. В итоге мне потребовалось более недели, чтобы добавить (или изменить) 180 строк кода. А это была всего лишь небольшая доработка программы.
Если бездумно писать код, то он получится плохим
Изменение этой программы было лишь частью гораздо большей задачи, связанной с модернизацией кода, написанного мною более десяти лет назад. Со своим материалом мне было гораздо проще, хоть я и плохо помнил, как именно работает этот код. Спецификации, которые я заблаговременно создал еще тогда, помогли мне с легкостью разобраться, что нужно переделать сейчас. Те изменения, которые мне пришлось вносить в собственный код, были на порядок объемнее, чем доработка упомянутого чужого кода, но у меня на это ушло всего вдвое больше времени, чем на чужой материал.
Что я понимаю под «чертежом», под спецификацией? Часто считается, что это – документ, написанный на строгом формализованном языке. Я считаю, что формальная спецификация – всего лишь один из возможных вариантов. Если мы хотим построить сарай, мы же не будем делать для него чертеж как для небоскреба. Аналогично при написании большинства программ можно обойтись без формальных спецификаций. Тем не менее глупо писать маленькие программы вообще без спецификаций – ведь даже перед строительством сарая стоит набросать простенький план.
В настоящее время я пишу программы, которые можно сравнить скорее с бунгало, чем с небоскребами. Обычно я указываю в спецификации каждый метод, и все методы настолько просты, что их можно описать в одной-двух строках. Иногда в методе решаются сложные задачи, над которыми требуется поразмыслить – тогда его спецификация может достигать по размерам целого абзаца и даже пары страниц. При этом я пользуюсь простым правилом: спецификация должна предоставлять всю информацию, необходимую для использования метода. После того как качественный код написан и отлажен, спецификация в идеале никому не должна понадобиться.
Как только я уясню, что должен делать код, написать его уже несложно. Конечно, так бывает не всегда, иногда требуется нетривиальный алгоритм. Чтобы написать алгоритм, необходимо подумать, а это значит – нужно приниматься за спецификацию.
При проектировании сложных систем строгая формализованная спецификация не менее необходима, чем подробный чертеж перед строительством небоскреба.
Практически все спецификации, которые я пишу, являются неформальными. Но иногда фрагмент кода бывает достаточно деликатным или критически важным, и без четко составленной спецификации не обойтись, ведь четкость необходима как для точности описания, так и для инструментальной проверки этого документа. Однако за последние десять лет мне приходилось писать спецификации подобного уровня меньше десяти раз.
При проектировании действительно сложных систем строгая формализованная спецификация не менее необходима, чем подробный чертеж перед строительством небоскреба. Тем не менее программисты редко пишут спецификации: на работе на это нет времени, да и в школе этому не учат. Лишь в некоторых вузах преподаются теоретические курсы по написанию спецификаций, но еще меньше – где учат обращению со спецификациями на практике. Конечно, сложно подготовить чертежи для небоскреба, если вы не вычерчивали их даже для сарая.
Писать сложно, а навыки письма приобретаются на практике. Нет простых правил, следуя которым, можно писать хорошие спецификации. Но могу посоветовать не использовать в спецификации код; ведь код не лучшим образом помогает понять другой код. Архитекторы не строят кирпичных чертежей.
Основной способ для понимания сложного материала – использование абстракций, необходимо выражаться на более формальном языке, нежели код. Самый лаконичный и одновременно точный язык – это математика, та самая, которую преподают на базовых математических курсах. Нужно уметь обращаться с множествами, функциями и простой логикой. Чтобы было проще создавать инструменты для проверки спецификаций, в большинстве языков для спецификаций присутствуют элементы, которые не изучаются в школьном курсе математики, например типы. Правда, следует учитывать: чем сильнее такой язык отдаляется от простой математики, тем больше смазывается абстракция, необходимая для понимания сложной программы или системы.
Неважно, идет ли речь о строгой формализованной спецификации для сложной системы или о неформальной спецификации для простого кода, главное осознать, что чем больше мы пишем спецификации, тем лучше программируем. Такие документы-«чертежи» помогают нам понимать, что мы делаем, и, следовательно, допускать меньше ошибок. Вместе с тем хорошо написанная спецификация еще не гарантирует абсолютно безотказной работы программы. Нам так или иначе придется пользоваться методами и инструментами, предназначенными для искоренения багов в коде.
Обдумывание работы не всегда спасает от ошибок. Но если работу не обдумывать, то ошибки вам гарантированы.
Лесли Лэмпорт – ученый-информатик, эксперт по распределенным системам, темпоральной логике и параллельным алгоритмам. Он является членом Национальной Академии Инженерных Наук и Национальной Академии Наук США. Доктор Лэмпорт получил степени доктора и магистра математических наук в Брандейском университете и степень бакалавра – в Массачусетском технологическом институте. В настоящее время Лэмпорт работает в исследовательском центре «MicrosoftResearch».
Источник: the wired
Примечание-размышление dev.by:
По традиции почти все статьи подобного рода от американских заслуженных гуру от software development и computer sciences имеют налёт «евангелизма». Мы все уже знаем, что если человек, который долго работал над серьезными проектами той или иной крупной компании, не ушел в менеджмент или преподавательскую работу, то со временем он переходит в разряд лица для конференций, масштабных тренингов и статей с рассказами о том, как хорошо на той или иной платформе, соблюдая все принципы, творить новые проекты. В данном случае «благая весть» не касается конкретного работодателя, а несет общеотраслевые истины.
В вышеприведенной статье Лесли размышляет о ментальных причинах, заставляющих сопротивляться работе над спецификациями сферических программистов, но в реальной жизни приходится сталкиваться с куда более прозаичными причинами. Вспомним столь распространенный у нас аутсорсинг. Зачем вообще заказчик им пользуется? Потому что он не хочет влезать во все эти дебри, ему нужен результат. Причем результат всегда нужен как можно быстрее и по возможности за меньшие деньги. А это некоторым образом «давит» на ответственных за оценку трудозатрат, в которые сложно вписывать задачи на расписывание спецификаций, особенно если учесть, что не всегда все участвующие в процессе звенья (от заказчика до реализаторов) четко представляют себе конечный итог. То есть совсем четко, а не на уровне абстракций, чтобы все желаемое работало, радовало, и играла неземная музыка. В результате в оценку закладывается в первую очередь программирование и тестирование с последующим допиливанием, но далеко не всегда – тщательная работа над спеками.
Далее. Многим из нас приходится работать именно с допиливанием, перепиливанием и адаптацией неких решений, то есть, по сути, с полуфабрикатом в том или ином виде и с тем или иным наличием спецификаций. Легко рассуждать об этом с колокольни личного распределения усилий на проектирование, когда сам рулишь проектом от и до, но несколько сложно придерживаться заповедей, работая над каким-то куском функционала.
Здесь можно упомянуть и уже почти повсеместно у нас распространенный Agile, который во многом призван решать проблемы понимания заказчиком процессов разработки, планирования и проектирования. Agile предполагает гибкое отношение к изначальной спецификации, учитывая высокую вероятность ее изменений. Да, практики управления всем этим «хозяйством» есть и давно используются, но на проекте, а не в теории, гибкость часто переходит в эластичность, когда разработка растягивается во всех возможных направлениях, потому что кто-то слишком Agile, кто-то верит в свой творческий гений, а стейкхолдер активен в строго определенные промежутки времени. Здесь возможности задания четкой спецификации или гибкого ее изменения опять-таки уменьшаются.
Разработка спецификаций частично затрагивает и такую область айтишной деятельности, как бизнес-анализ, которая достаточно активно развивается у нас в последние годы. Вопрос только в том, сколько у нас «настоящих» бизнес-аналитиков, имеющих достаточный опыт в формировании процесса разработки, а не прошедших двухмесячные курсы или играющих традиционную роль очередного звена по передаче требований и уламывания заказчика на те или иные компромиссные решения.
В целом, тема работы со спецификациями у нас выглядит даже более актуальной, нежели на Западе. И если сам Лесли не может толком провести грань между «свободными» спецификациями и формализованными, то в нашем случае зачастую это еще сложнее. Так или иначе, признак зрелости процесса разработки – это как раз умение лавировать между формализацией и гибкостью, между распределенностью и умением правильно выстраивать распределения ролей, описыванием функциональных задач и путей их решения в спецификациях. А оно приходит только с практикой и опытом, как и толковые спецификации на проекте. Можно утверждать, что это тема актуальна только для каких-то мелких проектах в аутсорс-компаниях, но, наверное, каждый может вспомнить свои эмоции по поводу недостаточности или, наоборот, гиперформализированности спецификаций на том или ином проекте в карьере.
Релоцировались? Теперь вы можете комментировать без верификации аккаунта.