CHAP1 (1018801), страница 2
Текст из файла (страница 2)
Эта проблема когда-то касалась почти исключительно машин Macintosh, но Windows и здесь в последнее время выходит вперед. Компьютер Mac был спроектирован так, чтобы прежде всего быть простым в освоении. Положим, что тетушка Матильда Мак-Гиликатти часто заходила в компьютерный магазин, чтобы пользоваться их услугой по моментальной печати кулинарных рецептов. В итоге Матильда забирает компьютер домой и успешно вводит рецепты в течение нескольких месяцев. Теперь она хочет взять эти рецепты, проанализировать их химический состав и написать статью в научный журнал о коллоидных свойствах продуктов питания на основе альбумина. Доктор Мак-Гиликатти - хорошая машинистка, печатающая обычно около 100 слов в минуту, но эта ужасная мышь ее постоянно тормозит. Каждый раз, когда ее руки отрываются от клавиатуры, она теряет несколько секунд. Она пытается найти слово в своем документе и обнаруживает, что для этого должна открыть меню, ввести текст в диалоговое окно и щелкнуть по нескольким экранным кнопкам. В конце файла она должна явно указать утилите поиска возвратиться к его началу. (Ее версия редактора vi 15-летней давности позволяет выполнить все это при помощи двух нажатий клавиш - без необходимости отрываться от клавиатуры). Наконец, она обнаруживает, что на выполнение обычной работы - подготовки статьи в журнал - уходит в два раза больше времени, чем раньше, в основном из-за проблем с пользовательским интерфейсом. Ей не понадобилось руководство, чтобы пользоваться этой программой, - ну и что?
Вернемся к примеру с карандашом из предыдущего параграфа. Очень трудно научиться пользоваться карандашом. У большинства детей это занимает несколько лет. (Вы могли бы возразить, что, судя по каракулям на рецептах, многие врачи этому так и не научились). С другой стороны, после того, как вы научились, карандашом пользоваться очень легко.
Главная проблема здесь состоит в том, что для опытного пользователя часто требуется совершенно другой интерфейс, чем для начинающего. Дополнительная помощь типа "горячих" клавиш не решает эту проблему; старый неуклюжий интерфейс пользователя все еще мешает продуктивности, и нет особой разницы: откроете ли вы меню при помощи "горячей" клавиши, или мышью. Здесь проблема в самом меню.
5. Производительность может измеряться числом нажатий клавиш.
Интерфейс, требующий меньше нажатий клавиш (или других действий пользователя типа щелчков мышью), лучше того, который требует много нажатий для выполнения одной и той же операции, даже если такие виды интерфейсов обычно сложнее в освоении.
Подобным образом пользовательскими интерфейсами, скрывающими информацию в меню или за экранными кнопками, обыкновенно труднее пользоваться, потому что для выполнения одной задачи необходимо выполнить несколько операций (вызвав подряд несколько спускающихся меню). Хороший пример - настройка программы. Во многих из используемых мной ежедневно программ опции настройки рассыпаны по нескольким меню. То есть для вызова диалогового окна, настраивающего один из аспектов того, что делает программа (например, выбор шрифта), я должен выбрать одно меню. Затем я должен вызвать другое меню, чтобы сделать что-то в том же духе (например, выбрать цвет). Лучше поместить все опции настройки на одном экране и использовать форматирование экрана для объединения опций по назначению.
6. Если вы не можете сказать это по-английски, то вы не сможете выполнить это на С/С++.
Это правило с последующим также относятся к правилам пользовательского интерфейса, но здесь под "пользователем" уже понимается программист, использующий написанный вами код - часто это вы сами.
Акт записи на английском языке описания того, что делает программа, и что делает каждая функция в программе, является критическим шагом в мыслительном процессе. Хорошо построенное, грамматически правильное предложение - признак ясного мышления. Если вы не можете это записать, то велика вероятность того, что вы не полностью продумали проблему или решение. Плохая грамматика и строение предложения являются также показателем небрежного мышления. Поэтому первый шаг в написании любой программы - записать то, что делает программа, и как она это делает.
Есть разные мнения о возможности мышления вне языка, но я убежден, что аналитическое мышление того типа, который нужен в компьютерном программировании, тесно связано с языковыми навыками. Я не думаю, что является случайностью то, что многие из знакомых мне лучших программистов имеют дипломы по истории, филологии и схожим наукам. Также не является совпадением то, что некоторые из виденных мной худших программ были написаны инженерами, физиками и математиками, затратившими в университете массу энергии на то, чтобы держаться как можно дальше от занятий по языку и литературе.
Сущность заключается в том, что математическая подготовка почти не нужна в компьютерном программировании. Тот тип организационного мастерства и аналитических способностей, который нужен для программирования, связан полностью с гуманитарными науками. Логика, например, преподавалась на философском факультете, когда я был в университете. Процесс, используемый при проектировании и написании компьютерных программ, почти полностью идентичен тому, который используется, чтобы сочинять и писать книги. Процесс программирования совсем не связан с теми процессами, которые используются для решения математических уравнений.
Здесь я делаю различие между информатикой (computer science) - математическим анализом компьютерных программ - и программированием или разработкой программного обеспечения - дисциплиной, интересующейся написанием компьютерных программ. Программирование требует организационных способностей и языковой подготовки, а не абстрактного мышления, необходимого для занятий математическим анализом. (В университете меня заставили проходить год на лекции по математическому анализу, но я никогда из него ничего не использовал ни на занятиях по информатике, хотя для них матанализ был необходимым условием, ни в реальной жизни).
Я как-то получил открытую рецензию на книгу, посвященную мной предмету проектирования компиляторов, в которой рецензент (который преподавал в одном из ведущих университетов) заявил, что он "считает абсолютно неуместным включение исходного кода компилятора в книгу о проектировании компиляторов". По его мнению, необходимо учить "фундаментальным принципам" - лежащей в основе математике и теории языка, а детали реализации - "тривиальны". Первое замечание имеет смысл, если у вас создалось впечатление, что книга написана ученым-специалистом по информатике, а не программистом. Рецензент интересовался лишь анализом компилятора, а не тем как его написать. Второе замечание просто показывает вам, насколько изолировала себя научная элита от реального труда программирования. Интересно, что основополагающая работа по теории языка, сделавшая возможным написание компиляторов, была выполнена в Массачусетском технологическом институте лингвистом Наумом Хомским, а не математиком.
Обратной стороной этой монеты является то, что если вы зашли в тупик при решении проблемы, один из лучших способов выйти из него - это объяснить проблему приятелю. Почти всегда решение возникает в вашей голове посредине объяснения.
6.1. Начинайте с комментариев.
Если вы последовали совету в предыдущем правиле, то комментарии для вашей программы уже готовы. Для того, чтобы получить документированное описание реализации, вы просто писали и добавляли вслед за каждым абзацем блоки кода, реализующие качества, описанные в этом абзаце. Оправдание "у меня не было времени, чтобы добавить комментарии" на самом деле означает "я писал этот код без проекта системы и у меня нет времени воспроизвести его". Если создатель программы не может воспроизвести проект, то кто же сможет?
7. Читайте код.
Все писатели - это читатели. Вы учитесь, когда смотрите, что делают другие писатели. Удивительно, но программисты - писатели на С++ и С - часто не читают код. Тем хуже. Я настоятельно рекомендую, чтобы, как минимум, члены группы программирования читали код друг друга. Читатель может найти ошибки, которые вы не увидели, и подать мысль, как улучшить код.
Идея здесь - не формальная "критика кода", имеющая довольно сомнительный характер: никто не хочет наступать на ногу коллеге, поэтому шансы получить полезную обратную связь в формальной ситуации малы. Для вас лучше присесть с коллегой и просто разобрать код строка за строкой, объясняя что как делается и получая какую-то обратную связь и совет. Для того, чтобы подобное упражнение принесло пользу, автор кода не должен делать никаких предварительных пояснений. Читатель должен быть способен понимать код, читая его. (Нам всем приходилось иметь дело с учебниками, столь трудными для понимания, что ничего нельзя было понять без объяснения преподавателя. Хотя это и гарантирует, что преподаватель не останется без работы, но никак не отражается на авторе учебника). Если вам пришлось объяснять что-то вашему читателю, то это значит, что ваше объяснение должно быть в коде в качестве комментария. Добавьте этот комментарий, как только вы его произнесли; не откладывайте этого до окончания просмотра.
7.1. В цехе современных программистов нет места примадоннам.
Это следствие из правила чтения. Программисты, которые думают, что их код совершенен, которые отвергают критику, вместо того, чтобы считать ее полезной, и которые настаивают на том, что они должны работать втихомолку, вероятно, пишут тарабарщину, не поддающуюся сопровождению - даже если кажется, что она работает. (Смысловое ударение здесь на слове кажется).
8. Разлагайте сложные проблемы на задачи меньшего размера.
На самом деле это также правило и литературного стиля. Если концепцию слишком сложно объяснить за один раз, то разбейте ее на меньшие части и объясняйте каждую по очереди. То же назначение у глав в книге и параграфов в главе.
Как пример, связанный с программированием, возьмем прошитое бинарное дерево, отличающееся от нормального дерева тем, что указатель на узел-потомок в концевом узле указывает на само дерево. Действительным преимуществом прошитого дерева является то, что его легко пересечь нерекурсивно при помощи этих дополнительных указателей. Проблема заключается в том, что сложно выйти из алгоритмов пересечения (в особенности обратного пересечения). С другой стороны, имея указатель на узел, легко написать алгоритм поиска последующего элемента в обратном порядке. Путем изменения формулировки с "выполнить пересечение в обратном порядке" на "начав с самого отдаленного узла, искать последующие элементы в обратном порядке, пока они не закончатся" получаем разрешимую задачу:
tree t; // дерево
node = postorder_first( t ); // исходный узел
while( node ) // есть еще узлы?
node = postorder_successor( t ); // следующий узел-родитель
9. Используйте весь язык.
9.1. Используйте для работы соответствующий инструмент.
Данное правило является спутником правила "Не путайте привычность с читаемостью", представленного ниже, но скорее больше касается проблем руководства. Мне часто говорят, что студентам не разрешается использовать некоторые части С или С++ (обычно это указатели), потому что они "нечитаемы". Обычно это правило навязывается руководителями, знающими ФОРТРАН, БЕЙСИК или какой-то другой язык, не поддерживающий указатели, ибо их не очень то заставишь изучать С. Вместо того, чтобы допустить, что их знания недостаточны, такие руководители будут лучше калечить своих программистов. Указатели отлично читаемы для программистов на С.
И наоборот, я видел ситуации, где руководство требовало, чтобы программисты перешли с языка программирования типа КОБОЛ на С, но не желало оплачивать переподготовку, необходимую для перехода. Или хуже, руководство платило за переподготовку, но не предоставляло времени, необходимого для действительного изучения материала. Переподготовка является занятием, требующим всего рабочего дня. Вы не можете одновременно выполнять "полезную" работу, а если попытаетесь, то ваши деньги будут выброшены на ветер. Так или иначе, после того, как руководители видят, что их штаб не был превращен в гуру программирования на С++ после 3-дневного краткого курса, они реагируют, накладывая ограничения на использование некоторых частей языка. Фактически говоря "Вы не можете использовать ту часть С++, которая не похожа на язык, который мы использовали до перехода на С++". Естественно, что будет нельзя эксплуатировать ни одну из прогрессивных особенностей языка - которые прежде всего и являются главной причиной его использования - если вы ограничите себя "простейшим" подмножеством особенностей.
Глядя на эти ограничения, мне в первую очередь интересно знать, зачем было менять КОБОЛ на С. Принуждение программистов на языке КОБОЛ использовать С всегда поражало меня своей большой глупостью. КОБОЛ - великолепный язык для работы с базами данных. У него есть встроенные примитивы, упрощающие выполнение задач, которые довольно трудны для С. С, в конце концов, был разработан для создания операционных систем, а не приложений баз данных. Довольно просто дополнить КОБОЛ, чтобы он поддерживал модный графический интерфейс пользователя, если это единственная причина перехода на С.
10. Проблема должна быть хорошо продумана перед тем, как она сможет быть решена.
Это правило с двумя последующими первоначально располагалось в начале этой главы. Подумав, я переместил их сюда, так как побоялся, что, прочитав их, вы пропустите оставшуюся часть главы. Однако в мои намерения не входит чтение проповедей. Эти правила посвящены весьма реальным проблемам и во многих отношениях являются самыми важными правилами в этой книге.
Настоящее правило является настолько очевидным утверждением в повседневной жизни, что кажется странным его восприятие как едва ли не ереси применительно к программированию. Мне часто говорят, что "невозможно потратить пять месяцев на проектирование, не написав ни одной строки кода - ведь наша производительность измеряется числом строк кода, написанных за день". Люди, говорящее это, обычно знают, как делается хороший проект; просто у них нет этой "роскоши".
Мой опыт говорит, что хорошо спроектированная программа не только работает лучше (или просто работает), но и может быть написана быстрее и быть проще в сопровождении, чем плохо спроектированная. Лишние четыре месяца при проектировании могут сэкономить вам более четырех месяцев на этапе реализации и буквально годы в период сопровождения. Вам не добиться высокой производительности, если приходится выбрасывать прошлогоднюю работу из-за существенных изъянов проекта.















