Архивы: по дате | по разделам | по авторам

Как проектировать ПО? 13 лет спустья

Архив
автор : Джек Ривз   05.05.2005

Меня порой спрашивают, получила ли какое-либо развитие статья «Что такое программное проектирование?». Ответ — отрицательный.

Статья впервые была напечатана в журнале «Developer.*» (developerdotstar.com) в феврале 2005 года и любезно предоставлена Джеком Ривзом для публикации в «Компьютерре». Перепечатка или распространение статьи возможны только с письменного разрешения автора. Мы также благодарим главного редактора «Developer.*» Дэниэла Рида за содействие в переговорах с автором.
«What is software design: 13 years later»,
©2005 by Jack W. Reeves.

Меня порой спрашивают, получила ли какое-либо развитие статья «Что такое программное проектирование?». Ответ — отрицательный. И дело не в том, что я забросил эту тему или изменил свои взгляды.

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

Вскоре после этой публикации «C++ Journal» канул в Лету, и я решил, что и мою статью поглотила некая пучина, в которой пропадает большая часть журнальных публикаций. Я переключился на другие занятия. Году в 97-м или 98-м по электронной почте мне пришло письмо от Боба Мартина (новоиспеченного редактора журнала «C++ Report»), в котором сообщалось, что на сайте Уорда Каннингэма (Ward Cunningham) c2.com моей статье посвящена wiki-страница. Это было первым свидетельством того, что кто-то ее прочитал (за исключением, конечно, тех, кому я лично вручил копию).

Я начал следить за дискуссиями на wiki-странице, иногда заглядывал в новостные группы, однако намеренно предпочитал не вмешиваться. Во-первых, я тогда работал над другими вещами; во-вторых, мне было ясно, что в профессионализме те, кто защищал мою позицию, не только не уступали мне, но иногда и превосходили (особенно мне запомнились реплики Майкла Физерса), и наконец, слишком уж много было у моей концепции противников. К сожалению, большинство аргументов мало отличались от тех, которые мне приходилось выслушивать на протяжении почти пятнадцати лет (напомню, что я вынашивал эту идею десять лет, прежде чем взялся за перо). Меня не вдохновляет общение с людьми, которые ни на минуту не способны подняться выше собственных предубеждений, хотя бы для того, чтобы просто выслушать чужое мнение. С тем же успехом можно учить французскому человека, который уверен, что любые иностранные языки — всего лишь диалекты английского. Не важно, что именно вы говорите, вас в лучшем случае перебьют, в худшем — начнут переубеждать. У меня было несколько проектов, в которых идея «проектирования в коде» работала, но даже те, кто участвовал в этих проектах, зачастую отказывались верить фактам. Скажи мне кто в ту пору, что ситуация может измениться, я бы тоже не поверил.

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

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

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

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

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

B.Сегодня, благодаря экстремальному программированию (eXtreme Programming) и «быстрым методам» разработки программ (agile methods), люди вынуждены, хоть и с большой неохотой, признать, что программисты вовсе не андроиды на конвейере. Однако, несмотря на это, они не готовы согласиться с концепцией исходного кода как проекта. Все возражения можно свести к следующей цитате (с той же wiki-страницы): «…Проектировать в коде с самого начала? Ха-ха-ха! Нет, правда? Ха-ха-ха!»

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

И все-таки они продолжают утверждать (переиначивая мою мысль), что предпосылка «код как проект» означает «не надо проектировать, надо кодировать». Да я в жизни не говорил ничего подобного. Я говорил:

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

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

Это главное. Я не предлагаю отказаться от проектирования. Но когда речь идет о процессе, я считаю, что его нельзя считать завершенным раньше, чем написан и протестирован код.

Лично мне кажется, что проектировать можно и задумчиво глядя в потолок, и тасуя UML-диаграммы в Rose. Если прежде, чем взяться за какое-то дело, вы его хорошенько обдумаете, то успех вам почти обеспечен. Чтобы мыслительный процесс протекал живее, люди используют самые разные средства. Кому-то необходима бумага и карандаш. Кому-то — «белый экран» или компьютер. Одни оттачивают свои идеи на аудитории, другим нужна тишина и покой. Кто-то оперирует диаграммами, теми же UML, кому-то больше нравятся CRC-карты.

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

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

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

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

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

B’ Не могу удержаться и не упомянуть, казалось бы, второстепенный вопрос, который часто возникает в дискуссиях об экстремальном программировании и так называемых быстрых методах: «Что делать, если программист недостаточно компетентен?» Видимо, считается, что проектировать и кодировать одновременно могут только гении. Стало быть, все предварительное проектирование необходимо, поскольку нам приходится иметь дело с обычными программистами и мы должны заложиться на отсутствие опыта и таланта.

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

В программировании вопрос о компетентности программиста обычно сводится к попытке замены процесса логикой, способностями и опытом. Очевидно, считается, что если заставить народ создавать больше UML-диаграмм (подставьте нужный инструмент), производить больше перекрестных проверок и всячески контролировать процесс детализации, то программисты вдруг поймут, чем они занимаются, и начнут кодировать лучше. Как показывает практика, подобный подход еще не увенчивался успехом, и нет оснований надеяться, что в будущем что-то изменится. Мой собственный опыт подсказывает, что грамотное использование надлежащих инструментов, например таких, как UML, сам по себе требует определенного уровня компетентности.

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

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

Когда в процесс проектирования вовлекается более двух человек или когда в нем формально выделена стадия производства, документация начинает принимать угрожающие размеры. Инженеры Toyota и Motorola занимаются производством документации, не говоря уже о сотрудниках Boeing и Lockheed. Наверняка обязанности многих инженеров не ограничиваются только этим, но каждый уважающий себя спец знает, как выглядит проектная документация в его области, и занимается ею скорее чаще, чем реже. Можно ли сказать то же самое о «софтверных инженерах»?

Точку зрения, касающуюся инженеров и документации, я выудил из статьи в журнале «Datamation» аж в 1979 году. И полностью ее разделяю.

D.И еще одно соображение — так сказать, вдогонку. Исходный код недостаточно детализирован, чтобы считаться проектом. По крайней мере, один критик называл исходный код «спецификацией». Он считал, что настоящий проект — это то, что выходит из компилятора. Это, конечно, до некоторой степени вопрос формулировки, однако я все же не согласен.

Общепринятое определение гласит: «спецификация» говорит что, а за ней следует проектная документация, которая детализирует как. Хотя компилятор допускает некоторую степень гибкости в определении как объектного кода, творческим подходом в этом процессе и не пахнет. И именно здесь я провожу черту. Документ только тогда может называться проектной документацией, когда он достаточно детализирован, полон и недвусмыслен, чтобы быть интерпретированным механически, вне зависимости от того, будет ли эта операция производиться компьютером или рабочим на конвейере. Если же требуется творческая человеческая интерпретация, называние должно быть иным.

В программировании проектная документация — это листинг исходного кода.

Экстремальное проектирование?

Рассуждения автора сводятся к простой мысли: кодирование — это не черная и тупая работа.

Кодирование — это принятие решений, и кодер — такой же участник процесса проектирования, как и архитектор проекта.

Следствие первое. То, что мы привыкли называть проектированием (то, что до кодирования), — штука, возможно, нелишняя, но и не принципиальная.

Следствие второе. Тестировать, тестировать и еще раз тестировать. Ибо исходный текст — это просто проект, и только тест позволит убедиться в его корректности.

То есть, по сути, нам предлагается еще одна апология экстремального программирования.

Я убежденный противник экстремального программирования и дочерних практик, таких как Agile Development. Причины тому наиболее четко изложены в статье Василия Пупкина «Extreme Programming considered harmful for reliable software development 2.0». Кратко: XP не предоставляет возможность гарантировать сколь-нибудь разумное качество результата; этот способ применим, только если программисты очень высокого класса, он не работает на больших проектах, а эффективность многих методик (в частности, парного программирования) вообще никем никогда не была подтверждена на практике или хоть сколь-нибудь логично обоснована.

Простая мысль: если другая методика разработки софта дает на 10% большую предсказуемость результата ценой на 100% (!) больших затрат программистских ресурсов, но без парного программирования, то она уже выигрывает у XP с его парным программированием (которое суть то же самое увеличение затрат на 100%).

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

В то же время многие практики XP вполне разумны. (Впрочем, увы, большинство реально применимых практик экстремального программирования заимствованы из других методик. То есть само по себе XP принесло мало полезного.)

Утверждение «Исходный код является последней стадией проектирования» имеет такое же право на жизнь, как и утверждение «Дом является последней стадией проектирования». Нравится? Правда, нравится? Давайте я проиллюстрирую построение дома по технологии экстремального программирования.

  • Вы (будущий житель) приходите на стройку к рытью котлована и сидите за спиной у тракториста. Воняет? Купите одеколону. Сидеть придется до готовности дома.
     
  • Тракторист спрашивает вас: «Ну как, котлован достаточно глубокий?» Откуда вам знать? Ну вы же заказчик. Должны знать. Заодно определитесь с тем, какое сечение должны иметь силовые кабели, можно ли соединять газовые трубы сваркой, и какого типа нужен цемент.
     
  • Когда дом вчерне построен, приезжает эдакая дура с чугунной чушкой на веревке и долбасит по стене. Если дом разваливается, его стоят заново, укрепив получше в тех местах, где треснуло. Пожалуйста — придумайте сами, почему вы должны оплатить строительство трех домов, а получить только один. Я не знаю.
     
  • Когда вы включите в розетку чайник и провода загорятся, ваша претензия не будет принята — в вашем присутствии розетку проверяли втыканием лампочки, и вы согласились, что она работает нормально.

     

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

    Экстремальное программирование — вообще ужасно наивная идея. Например, посадить заказчика рядом с программером, чтобы он рассказывал, как делать, можно, только если:

     

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

    Можно долго говорить о том, насколько XP отличается от детского лепета, но есть и другая сторона медали. Коль скоро XP появилось, тому были какие-то предпосылки. Как бы само решение ни было несерьезно, нужно посмотреть на причины, которые к нему привели, и, может быть, предложить иное решение.

    A.Автор утверждает, что проектирование не закончено, пока последняя строка кода не написана и не оттестирована. По сути это означает следующее: никакой проект не транслируется в код 1:1. В настоящее время это утверждение вполне справедливо.

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

    B. Автор фактически подтверждает, что XP ориентирована на высококлассных программистов и не работает, если программист — среднего уровня. «Пусть все программеры будут классными», — говорит автор. Иллюстрирую: не будем проектировать автомобили, не будем давать рабочим технологические карты. Вместо этого наймем таких рабочих, чтобы сами по месту разбирались, что к чему. Наивность этого подхода подтвердил Форд запуском первого конвейера около ста лет тому назад. То есть XP применять можно, но — вот беда! — экономически невыгодно.

    C.Терминологический вопрос. Несущественно.

    D.В рамках авторской теории это правда, за рамками — не имеет смысла. Так что обсуждать нечего.
    Резюме: несерьезно. Все это очередной завуалированный разговор на тему «не хочу ничего делать, кроме кодирования и — так уж и быть — тестирования». Почему? Да потому, что не умеет. Так пусть учится!

    Дмитрий Завалишин
  • © ООО "Компьютерра-Онлайн", 1997-2024
    При цитировании и использовании любых материалов ссылка на "Компьютерру" обязательна.