СОЛО на клавиатуре

Поговорим о программировании

03.05.2010

Размышления бывшего программиста. Часть 6 (окончание сериала)

Желание поболтать по душам на тему «программирования вообще» появилось давно, но меня всегда останавливало осознание того, что я уже несколько лет как отошел от реального программирования (создания продуктов, а не баловства на уровне написания тестовых примеров).

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

Что же такое хорошая программа? Этот вопрос обсуждался в 3-й части моих заметок, и дискутировать на эту тему можно довольно много. По этому поводу хотелось бы еще раз высказать свою точку зрения: работоспособность программы является необходимым, но не достаточным условием. Нельзя проводить оценку программы в отрыве от сроков ее написания, трудозатрат, возможности сопровождения и ряда других характеристик. И вот именно здесь на первый план выходит тема «стиля программирования», потому что даже при поверхностном рассмотрении легко увидеть, что речь тут идет не о моде или абстрактных правилах хорошего тона, а о насущных вопросах повышения производительности работы программиста, увеличения надежности программ, снижения стоимости их сопровождения, обеспечения групповой работы и т.д. Более того, в ряде случаев качество исходного кода является даже более приоритетным, чем его работоспособность. Я имею в виду в первую очередь фрагменты учебного кода.

Пишите комментарии

Комментарии в исходном тексте — это просто классический пример вечного вопроса программирования. Казалось бы, все «точки над i» расставлены еще 30 лет назад, так нет же — огромное множество современных программистов продолжают считать комментарии блажью начальников проектов, признаком непрофессионализма и пр.

Вот что писал по этому поводу Эд Йордан более 25 лет назад: «В области программирования ничто не заслуживает большего порицания, чем программа без комментариев. Программисту можно простить многие прегрешения и фантазии, однако ни одному программисту, как бы ни был он умен и опытен, нельзя простить программу, не оформленную и не содержащую комментариев... Только глупец может идти незнакомым лесом, не оставляя за собой знаков. Писать программы без комментариев — это то же самое, что пробираться джунглями Амазонки с завязанными глазами...»

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

 cmp dl,0  
 jne Attrnext  

или при использовании идентификаторов ограниченного размера:

If A > 0 Then B = C + D

проблема описания программы выглядела совсем иначе, чем для современных языков:

If blnFlagShow = True Then  
  Me.WindowState = vbMaximized  
End If 

Прежде чем рассказывать о том, как и зачем писать комментарии, приведу несколько характерных доводов (на самом деле — оправданий) по поводу их отсутствия в программах:

— У меня нет времени, чтобы делать какие-то комментарии.

— Моя программа ясна сама по себе.

— Всякий компетентный программист может понять мою программу.

— Моя программа будет использоваться только один раз, так что в ее оформлении нет никакой необходимости.

— Эта программа наверняка подвергнется серьезным изменениям во время отладки, и к моменту их завершения комментарий уже устареет.

— Я прекрасно понимаю, что делает моя программа, — зачем же её комментировать?

— Я не люблю оформлять или комментировать.

— Иметь слишком много комментариев вредно — это делает неясным смысл наиболее важных из них.

— Пояснения! Да кто их вообще читает?

Наверняка, каждый из современных руководителей проектов не раз слышал такое от своих сотрудников. Но все приведенные выше высказывания я взял из той же книги Йордана выпуска 70-х годов. Лишь несколько из имеющихся у него «доводов» действительно устарели (например, желание экономить дисковую память и лимит времени перфоратора при вводе исходного текста).

А из более современной практики хотел бы добавить такие тезисы:

— Не хочу оскорблять тех, кто будет изучать мой код, недоверием к их квалификации.

— Не программистское это дело (как и написание документации), для этого есть технические писатели.

— У нас есть специальная программа, которая автоматически расставляет комментарии на основе анализа кода.

Против первого высказывания трудно придумать весомые аргументы, кроме пожелания заняться сопровождением программ без описаний. Что же касается двух последних, то здесь хотелось бы сразу привести контрдоводы.

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

A = A + 1  ' увеличиваем A на 1
Exit Sub   ' завершение процедуры  

А вот примеры «поясняющих» комментариев, которые вряд ли сможет расставить какая-то утилита:

ShowCol.AllowDBNull = False  ' неопределенное значение недопустимо   
InsertFlag = Not InsertFlag  ' изменение режима ввода символов   
If index = 0 Or KeyAscii = 127 Then  ' переход в режим редактирования

А вот еще один реальный пример. Около 15 лет назад я отправил в редакцию одного журнала статью, которая содержала такой фрагмент кода:

   out     dx,al  
   mov     al,es:[bx]  ; нужен ли этот оператор?  
   mov     es:[bx],cl  
   mov     dx,3CEh  
   mov     al,5  

Редактор в журнале оказался очень внимательным: он изучил код и увидел в нем явно лишний оператор (который помечен комментарием). Действительно, в нем выполняется пересылка какого-то значения в регистр A, который нигде не используется, а двумя операторами ниже формируется еще раз. Поэтому редактор удалил эту строку, а после публикации мне стали звонить читатели и говорить, что моя программа не работает.

Дело в том, что данный ассемблерный код из-за специфического использования источника информации (es:[bx] — адрес видеопамяти) выполняет не только формирование регистра A, но и скрытого регистра задвижки (другого способа в процессоре 286 не было). Так вот, если бы я зафиксировал, зачем делается этот трюк, в комментарии, то никакого недопонимания между мной и редактором не возникло бы. Конечно, править авторский код редактору в любом случае недопустимо, но такая ситуация могла бы легко возникнуть не только при сопровождении программы другим разработчиком, но и если бы мне самому пришлось корректировать код пару месяцев спустя (я бы просто уже забыл о набитых шишках).

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

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

«Написание комментариев — это признак хорошего тона» (из известной книги по программированию российского автора). Эту фразу можно истолковать так, что это некоторая дань моде, а не требование технологии.

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

Конечно же, комментарии не являются самоцелью и в любом случае не заменят плохих кодов. Понятно также, что большие трудности могут возникнуть и в случае, когда программа насыщена комментариями, но при этом они (ссылаюсь здесь на [3]):

избыточны;

устарели;

были и остаются ошибочными;

неоднозначны и неточны;

правильны, но неполны;

не понятны никому (кроме автора).

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

В начале процедуры пишите заголовок, в котором указывайте, что она делает. Здесь нужно привести описание всех используемых в ней внешних ресурсов — процедур, объектов, переменных. Пример очень простой: вы загружаете некий (собственный) модуль, вам сообщается о неопределенных ссылках, но вы не можете вспомнить, где они находятся (причем трудно понять — речь идет о свойстве какого то объекта из какой то библиотеки или о глобальной константе).

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

Комментируйте каждую управляющую конструкцию (в VB — Do...Loop, For...Next, Select Case). Отмечайте все нетривиальные выходы из таких конструкций.

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

О тестировании и написании документации

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

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

Что касается тестирования, то тут следует вспомнить, что одной из главных причин перехода к структурному программированию в начале 70-х годов была необходимость снижения затрат на тестирование. Именно этот аспект был в центре внимания фундаментальной работы Э.Дейкстры. (В далёком 1972 году он сформулировал очевидный сегодня постулат: «Тестирование программ может служить для доказательства наличия ошибок, но никогда не докажет их отсутствия!»)

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

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

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

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

Хочу подчеркнуть — я это делал не только из желания обеспечить комфортные условия для клиентов. Тут были и гораздо приземленные причины — мне было проще скорректировать код, снизив свои затраты на подготовку документации.

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

Внимание: маркетинг!

Говоря об общности базовых принципов программирования на протяжении всей истории его существования, нужно, конечно, иметь в виду и то, что технология эта развивается и знака тождественного равенства между разработкой ПО 70-х и 90-х годов поставить никак нельзя. Хотя все очень похоже... Но есть один принципиально новый элемент современного программирования, которого не было два десятилетия назад и которое оказывает очень серьезное влияние на разработку ПО. Его имя — маркетинг.

Действительно, почитайте публикации 70-х годов. Там ведется обсуждение проблем программирования на академическом уровне, ученые проводят сравнительный анализ языков, рассматривают пути повышения эффективности работы программистов и самих программ, ищут истину... Бескорыстно! Если обсуждается конкретный язык программирования, то практически не уточняется, кто является разработчиком компилятора и о какой версии идет речь. Не говоря уже о том, что одной из популярных тем тех лет был сравнительный анализ разных языков. (Кто-нибудь из читателей видел современную книгу со сравнительным анализом, например, VB и Delphi? В лучшем случае в одной книге есть отдельные разделы по разным средствам, но без каких-то попыток сопоставления.)

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

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

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

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

«Не верь, не бойся, не проси!»

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

Так вот, недавно я обнаружил еще одну книгу, которая произвела на меня примерно такое же впечатление. Ее автор — Дан Эпплман, очень известный американский разработчик. Несколько лет назад он создал компанию Desaware, которая занимает заметные позиции на рынке дополнительных продуктов, в основном для VB. Но еще большую популярность он заслужил как автор целого ряда книг (его серия о Win API для VB в течение почти 10 лет неизменно является бестселлером), а также огромного количества статей, в которых он интересно рассматривает не только технические, но и маркетинговые вопросы.

Его книга, переведенная и опубликованная издательством «Питер», произвела на меня огромное впечатление, потому что она написана именно так (и в таком стиле), как я всегда хотел изложить свое видение проблем современного программирования вообще и с помощью VB в частности. (Конечно, известность Дана Эпплмана для меня является недостижимой, но кое-что общее у нас имеется: я тоже зарабатывал деньги созданием инструментального ПО для Basic/DOS — и написал немало статей. И еще: последние 20 лет использую средства разработки Microsoft и пишу о них.)

Я искренне советую всем программистам найти и прочитать эту книгу, потому что в ней говорится не столько о VB и основах платформы .NET (это лучшее, на мой взгляд, описание .NET из всего множества публикаций на эту тему), сколько о методике изучения новых инструментальных средств. Красной нитью через изложение проходит также обсуждение вопроса «технология и маркетинг». И сейчас я хочу привести лишь несколько цитат из книги (по поводу них я могу лишь высказать сожаление, что Дан опередил меня с точным изложением моих собственных позиций):

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

На самом деле я уважаю Microsoft. В ее изделиях встречается немало хороших технологий, совсем немножко технологий замечательных и удручающе много рекламной шумихи на пустом месте. (Прим. авт.: От себя добавлю: все высказывания о Microsoft относятся к любой другой крупной ИТ-компании. Замените слово «Microsoft» на «IBM», «Sun», «Oracle»...) Маркетинговый отдел Microsoft работает исключительно эффективно, хотя его действия порой кажутся совершенно непостижимыми.

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

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

Все сказанное Microsoft (или любой другой компанией) следует воспринимать скептически и оценивать в контексте конкретной ситуации. Приступая к решению любой проблемы, необходимо прежде всего выяснить, существует ли она. В один прекрасный день выяснилось, что Microsoft начинает отставать от Netscape, Sun и других компаний, занимающихся Интернет-технологиями. Немедленно под фанфары появилась новая технология ActiveX. Что такое ActiveX? Это OLE2 с новым названием.

В начале 2000-х годов все упоминания о Windows DNA исчезли буквально за считанные дни, а на смену им мгновенно пришло нечто, называемое .NET Enterprise Services. Более того, Microsoft даже опубликовала список соответствия терминов DNA и .NET. (Прим. авт.: Я был на презентации, где семейство Windows 2000 Server было обозначено как .NET Server Family.)

Заключение

Закончить свои «Размышления» я хочу еще одной цитатой из книги Дана Эпплмана: «Всё сказанное мною (или любым другим автором) следует воспринимать скептически и оценивать в контексте конкретной ситуации».

Ваш Андрей Александрович Колесов


← назадоглавлениедалее →

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


Ваш комментарий будет опубликован после модерации.


Rambler's Top100
ErgoSolo
© 1997— «ЭргоСОЛО»
Дизайн: Алексей Викторович Андреев
Вебмастер: Евгений Алексеевич Никитин
Пишите нам:
Звоните нам по тел. +7 (495) 995-82-95. Мы работаем круглосуточно. Прямо сейчас на все Ваши вопросы готова ответить наша служба поддержки:
Круглосуточная трансляция из офиса «ЭргоСОЛО»

Поможем бросить курить
Все права на материалы, находящиеся на сайте ergosolo.ru, охраняются в соответствии с законодательством РФ, в том числе, об авторском праве и смежных правах.
Использование материалов сайта без разрешения ООО "ЭргоСоло" ЗАПРЕЩЕНО!