Как писать компьютерные программы

Перевод статьи How to Write Computer Programs, автор - Gary D. Knott

 

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

Важным моментом является то именно это: {объяснять каждую деталь каждого аспекта программы в нужный уровень детализации только правильным способом и в нужное место, и убедитесь, что это тело объяснений становится лучше, более полное, и более правдивым со временем.} Большая часть остальной части этой статьи состоит в разработке этой точки.

Конечно, успешно документирования, записи и поддержание системы компьютерных программ не гарантирует, что система прекрасна, или что у него есть полезность, или что она воспринимается как стоит, или что стоит. Эти вопросы имеют отношение к суждения, вкуса, знания, опыт, дизайна и продвижения по службе. В самом деле, как с практической точки зрения, писать хорошо продуманные хорошо документированную программу, как правило, не в верхней части списка приоритетов; `` Маркетинг '' (т.е. достижение уведомления), как правило, самый важный вопрос, так как, если мало кто замечает, что не может быть целесообразным, чтобы написать программу любого рода, если программа не является личным выражением предполагается либо редко используется, или быть `` искусство ради искусства ". Тем не менее, хотя маркетинг может быть главным приоритетом, хороший дизайн и хорошая документация не следует игнорировать, даже в тех, к сожалению, слишком распространенные ситуации, где они могут быть проигнорированы.

Основная причина того, что затраты на программирование высоки, что большинство программ включает в себя работу на код, написанный месяцами или даже годами раньше; и большая часть усилий включает в себя обучение или переобучения цели, функциональность, контекст, стратегии, используемые, библиотеки подпрограмм и иного развития `` пособия '' используется и ввода / вывода кода ведутся работы. Если код написан как своего рода учебник `` '', будущая работа сделана {много} проще. Конечно, возникают те же проблемы при использовании программных средств, предоставляемых другими людьми без надлежащей документации.

{Как обстоят дела}

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

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

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

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

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

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

Тематические исследования: APL, MUMPS, SPEAKEASY, MLAB, MACSYMA, REDUCE, MATLAB, TEX, BASIC, KERMIT, LISP, UNIX, HYPERCARD, WYLBUR, EMACS, MOSAIC, POSTSCRIPT, SAS, SPSS, PKZIP, PGP.

{Стратегия Программирования}

Многие коммерческие программы (или свободные, но хорошо расцененный программы) в основном библиотеки подпрограмм (например, некоторые системы баз данных, численные подпрограммы, GUI-строители, оконные системы.) Подпрограммы библиотеки являются единственной успешной формой `повторно используемого программного обеспечения '' '.(Так называемый класс библиотеки C ++ и т.д., по сути, частным случаем библиотеки подпрограмм.) Другие коммерческие программы по сути являются монолитом, то есть один или несколько программ, посвященных единой цели (например, компилятор-линкер-отладчик комплекс, продуманная программа для обработки текста, как EMACS или вычислительный инструмент, как Mathematica или MLAB.) Многие из таких, по-видимому монолитные программы, однако, естественно, требует создания библиотеки подпрограмм, которая формирует основные компоненты системы или систем, которые являются конечным продуктом. Трудно создавать и поддерживать такую ​​библиотеку. Одной из главных причин в том, что требования к документации выше, где мы явно создании программного обеспечения для `` повторного использования '', либо "аутсайдеров" либо внутренней командой разработчиков (плюс другие команды в последующие годы.) Тем не менее, как правило, хорошо стоит усилие в качестве устройства для систематизации, если ничего другого.

Вопросы, которые смягчают против построения надежной библиотеки подпрограммы являются: (1) платформы и ограничения языка (даже `` же '' язык на тот же компьютер не полностью совместимы между составителями.) (2) проблемы документации (стандарт необходим для удобства использования очень высока,) (3) последовательной и хорошо подобранный дизайн, и (4) решимость и ресурсы для ручной клади на продолжающийся обслуживание и Improvment усилия.

Условное включение кода, управляемый {IfDef} -подобных конструкций является эффективным решением для большинства, но не все платформы и языка несовместимости;структура конвенции обивка и прямой порядок байтов по сравнению с вопросами тупоконечника являются примерами трудностей, которые не могут быть полностью решить эту проблему с помощью {ifdefs}.

Это удивительно для меня, насколько труднее программирование стало за последние 30 лет.В `` рано '' дней, программирование было интеллектуально интересно, но утомительно, а также отсутствие информации была лишь умеренная проблема; совсем недавно, программирование стало менее утомительным (из-за множества инструментов разработки программного обеспечения), но более сложно. Конечно, наши стремления постоянно растут, и наши достижения неизменно превосходит наше понимание; но инструменты не поспевают с нашими потребностями (или в некоторых случаях опережают наши потребности, сопровождающееся чрезмерной сложности.) Компьютеры, операционные системы, механизмы межпроцессного взаимодействия, и отладчики все становятся все более сложными и сложнее в использовании, как правило, без компенсирующую увеличение функциональности. Избыточный словарный запас и концептуальный туман обнародован мириады интересов борьба за позиции и ищет внимания, не заботясь о понимании имеет много общего с этим печальным положением дел, равно как и недостаточное, недоступной, или несуществующий документации.

Самой распространенной формой проблемой сталкиваются программисты, чтобы ответить на вопрос `` Как мне делать, х '', где х, как правило, некоторые концептуально простой функции, такие как включение и обработку прерываний, доступ к какой-то определенный системой структуры данных операционной, или при выполнении некоторые GUI связанные ввода / вывода задачи. Именно отсутствие источников документации, что является основной причиной нашего горя, и неадекватность наших инструментов проходит второе место. Было бы значительным шагом вперед, если наиболее распространенные проблемы для программистов были разработка алгоритмов и интерфейсов, а не непрекращающейся борьбы с тем, что по праву должно быть вспомогательные вопросы, связанные с программным обеспечением других народов. Документация не paneca, но {} является единственным наиболее важным лечебным, которые могут быть введены.

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

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

{Оказание помощи программатора: Документация}

При документировании программы, существует несколько распространенных ошибок, которые можно избежать, следуя максиме: {Говори правду, всю правду, и делать это с точностью}. Очень важно, чтобы описать все структуры данных, в том числе простых переменных; такие описания не должны быть полными неопределенных терминов и жаргона. Должна быть предусмотрена возможность для `` Разглядеть '' программа, нечто вроде книги. Конечно, есть последовательные ограничения, но избыточность может использоваться разумно, чтобы помочь браузеров.

Удивительно, сколько программистов, когда их просят документировать такую ​​строку: '' A = B '' считают, что это само собой разумеющееся и даже написать что-то вроде: / * множество А к В * /. То, что требуется больше похож: / * сохранить адрес отсортированного матрицы В в так B может быть восстановлена ​​после вызова сверку () * /. Другими словами, мы хотим объяснить на стратегическом, алгоритмических и концептуальных уровнях. Главное в том, что, в отличие от программиста во время кодирования, читатель на более поздний срок не может понять (или вспомнить) функциональное значение переменных манипулируют без посторонней помощи. Даже когда мы думаем, что мы находимся на вершине вещей во время высокой температуры кодирования, используя дисциплину, участвующих в описании того, что мы предлагаем сделать это часто бывает полезно для уточнения нашего собственного мышления. Некоторые люди выступают за использование длинных описательных имен переменных, но это, как правило, неприятно для математически подготовленных читателей.

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

Текстовый файл, содержащий код документа; он должен иметь стандартную структуру и должна быть легко развертываемых для того, чтобы пятно, импортированных и экспортированных глобальные объекты данных и подпрограммы. Сам код должен иметь стандартную структуру в отношении отступы, соответствия скобок, заявление разделов и вложенных комментариев. Если разные программисты следуют различные соглашения, последующее чтение становится очень намного сложнее, и {наиболее важным аспектом разработки программы является ее читаемость}. Считываемый программа может быть легко восстановлена, если он misprogrammed. Нечитаемым программа не может быть легко восстановлены!

Если вы хотите увидеть , что я считаю хорошо документированный читаемую программу, код, приведенный в www.civilized.com/files/msgfuncs.txt

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

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

Разумное абстракция является очень ценным, он скрывает ненужные детали и, таким образом, позволяет нам сосредоточиться на главном. Но деталь одного человека является еще одним важным компонентом это. Кроме того, в текущем и в обозримом будущем состоянии программирования, нельзя безопасно получить очень далеко от основной байт-компоновки различных объектов данных; попытки скрыть физические факты, как правило, больно усилия отладки и обслуживания больше, чем это помогает. Возможно, нам необходимо знать, например, точные шестигранные-коды различных шаблонов, таких как '\', или точного расположения записи каталога файлов. Отсутствие знаний о том, как `` программно-INTERRUPTS '' работы, и какие места используются программой, и для каких целей, был генезис огромного количества проблем.

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

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

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

Обратите внимание, что мы разместили мало внимания на вопросах языка программирования в этой статье. Хотя некоторые языки более удобны, чем другие, то легко писать непонятную код практически на любом языке. Обратное утверждение верно лишь отчасти; языки с неадекватные условия для работы с структур данных и глобальной против локальной области видимости, как более старые варианты Fortran, Basic, или LISP, труднее орудовать чем другие, более современные языки. Основной вопрос, который большинство программистов борются с при использовании конкретного языка, однако, проблема недостаточной мощности, чтобы выразить необходимую логику (например, прямое взаимодействие с операционной системой - т. Е вызывающей функции системы Часто некоторые программы на языке ассемблера необходимо, как и в написании обработчиков прерываний, например.) тем не менее, дисциплинированный программирования и документирования с упором на ясность, как правило, более важным, чем выбор языка программирования.

{Помогающая пользователю}

Пользовательская документация должна рассматриваться как расширение документации общую производительность системы. Важно, чтобы там быть {полный} справочное пособие в дополнение к вводным руководства. Иногда эти два руководства могут быть смешаны, но часто учебник введение с большим количеством примеров находится в противоречии с тщательной математически точным эссе. Часто справочное руководство не будет сделано, и пользователю остается, чтобы получить представление о системе путем индукции его поведение из примеров; это не добродетель и не уважает время пользователя. То же жалоба относится к большинству ручной менее GUI на основе конструкций; они призваны быть простым, но на самом деле они, как правило, всего лишь рамки, в которых угадывание может быть сделано.

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

Пользователю необходимо иметь согласованную функциональную модель программы даже больше, чем программиста. Несмотря на то, `` настольного метафора '' ГПИ с переноса данных между программами как gussied вверх по оконного-системы посредников продвигаются как почти универсальное решение в эти дни, я считаю, что большинство пользователей, включая меня, как правило, озадаченный относительно того, что это большую часть времени происходит. Единственным противоядием этой путаницы, кажется, большая доза правды. Когда выработок программы представлены в функциональных терминах, используемых программистами, мы видим за кулисами достаточно, чтобы стать более совершенным пользователей.

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

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

Wirth, Niklaus, ``A Plea for Lean Software'', IEEE Computer, Vol. 28, No. 2, pp. 64:68, Feb. 1995