Страница:
действует в интересах пользователя при поиске компромисса между функциями,
техническим характеристиками, размером, стоимостью и выполнением графика
работ. Выполнение этой задачи требует полной занятости, и только в очень
маленьких группах может быть совмещено с должностью руководителя.
Архитектора можно сравнивать с режиссером, а менеджера - с продюсером
кинокартины.
Отделение архитектуры от разработки и реализации. Чтобы сделать
возможным осуществление архитектором своей главной задачи, необходимо
отделить архитектуру, т.е. определение продукта в восприятии пользователя,
от его разработки. Архитектура и разработка определяют четкую грань между
разными частями задачи проектирования, и по каждую сторону этой грани лежит
большая работа.
Рекурсивность архитектуры. В очень больших проектах одному человеку не
справиться со всей архитектурой, даже если он избавлен от всех забот,
связанных с разработкой. Поэтому главный архитектор системы должен разбить
целое на подсистемы. Границы подсистем должны быть проведены так, чтобы
интерфейсы между ними были минимальны и легче всего строго определяемы.
Тогда у каждой части может быть свой архитектор, подчиняющийся главному
архитектору системы в отношении архитектуры. Очевидно, при необходимости
этот процесс может быть продолжен рекурсивно.
Сегодня я убежден более чем когда-либо. Концептуальная целостность
является важнейшим условием качества продукта. Наличие системного
архитектора есть важнейший шаг в направлении концептуальной целостности. Эти
принципы ни в коей мере не ограничиваются разработкой программного
обеспечения, а справедливы при проектировании любой сложной конструкции,
будь то компьютер, самолет, стратегическая оборонная инициатива или система
глобальной навигации. После преподавания в более чем 20 лабораториях
разработки программного обеспечения я стал настаивать, чтобы группы
учащихся, даже из четырех человек, выбирали менеджера и отдельно -
архитектора. Разделение функций в таких маленьких группах может показаться
несколько чрезмерным требованием, но, по моим наблюдениям, это оправдано и
способствует достижению успеха.
Эффект второй системы: функциональность и угадывание частоты
Проектирование для больших групп пользователей. Одним из последствий
революции, произведенной персональными компьютерами, является все
возрастающее, по крайней мере в области обработки деловых данных, вытеснение
заказных программ коробочными программными пакетами. Более того, стандартные
программные пакеты продаются сотнями тысяч и даже миллионами экземпляров.
Системные архитекторы программ, поставляемых вместе с машиной, всегда должны
были создавать проект, ориентированный на большую аморфную массу
пользователей, а не на отдельное определенное приложение в одной компании.
Теперь такая задача встает перед очень многими архитекторами.
Парадокс состоит в том, что спроектировать инструмент общего
назначения, нежели специализированный, гораздо труднее именно потому, что
нужно придать вес различающимся потребностям разных пользователей.
В погоне за функциональностью. Архитектор инструмента общего
назначения, такого, например, как электронная таблица или текстовый
редактор, подвержен сильному соблазну перегрузить продукт функциями
предельной полезности ценой снижения производительности и даже простоты
использования. Вначале привлекательность предлагаемых возможностей кажется
очевидной. Расплата производительностью становится очевидной лишь при
системном тестировании. Утрата простоты использования коварно подкрадывается
по мере того, как небольшими порциями добавляются новые функции, а
руководства пользователя все более разбухают.1
Соблазн особенно велик в отношении долгоживущих массовых продуктов,
развивавшихся на протяжении ряда поколений. Миллионы покупателей требуют
сотен новых возможностей. Всякая просьба свидетельствует о наличии спроса на
рынке. Часто архитектор первоначальной системы уже ушел в поход за новой
славой, и архитектура оказалась в руках людей с меньшим опытом взвешенного
представления общих интересов пользователей. В недавней рецензии на
Microsoft Word 6.0 сказано: "Переполнен возможностями; обновление замедлено
перегруженностью... Кроме того, Word 6.0 занимает много места и медленно
работает." С неудовольствием отмечается, что Word 6.0 занимает 4 Мбайт
памяти и сообщается, что из-за богатых дополнительных функциональных
возможностей "даже Macintosh IIfx едва пригоден для выполнения Word 6".2
Определение группы пользователей. Чем крупнее и аморфнее группа
предполагаемых пользователей, тем более необходимо явно ее определить, если
вы намерены достичь концептуальной целостности. У каждого члена группы
проектировщиков наверняка есть неявный мысленный образ пользователя, и все
образы будут отличаться друг от друга. Поскольку представление архитектора о
пользователе явно или подсознательно оказывает влияние на все архитектурные
решения, важно, чтобы команда проектировщиков пришла к единому общему
образу. Для этого необходимо составить список признаков предполагаемых
пользователей, указав в нем:
- кто они такие,
- что им нужно,
- что, по их мнению, им нужно,
- чего они хотят.
Частоты. Для любого программного продукта каждая характеристика
пользователя представляет собой распределение со множеством возможных
значений и соответствующими частотами. Как архитектору получить эти частоты?
Изучение этой слабо очерченной популяции представляется сомнительным и
дорогостоящим занятием.3 С годами я пришел к убеждению, что архитектор
должен угадать или, если вам больше нравится, постулировать полный набор
признаков и значений вместе с частотами для создания полного, явного и
общего для всех описания группы пользователей.
Такая непривлекательная процедура имеет ряд полезных последствий.
Во-первых, при стремлении точно угадать частоты архитектор вынужден очень
тщательно обдумать, какова возможная группа пользователей. Во-вторых, при
фиксации частот возникает обсуждение, полезное для всех участников и
выявляющее различия в образах пользователя, имеющихся у разных
проектировщиков. В-третьих, явное присвоение частот содействуют пониманию
того, какие решения какими свойствами группы пользователей обусловлены. Даже
такой неформальный анализ чувствительности приносит пользу. Когда
обнаруживается, что очень важные решения зависят от некоторых специфических
предположений, оказывается уместным получить более точные численные оценки.
(Разработанная Джеффом Конклином (Jeff Conklin) система позволяет формально
и точно прослеживать принятие проектных решений и документировать их
основания.4 Мне не приходилось ею пользоваться, но думаю, что она должна
быть очень полезна.)
Подводя итоги: установите предположительные признаки группы
пользователей. Гораздо лучше ошибаться, но выражаться ясно, чем выражаться
туманно.
Как насчет эффекта второй системы? Один наблюдательный ученый заметил,
что "Мифический человеко-месяц" рекомендовал на случай неудачи для всякой
новой системы планировать поставку второй версии (см. глава 11), которая в
главе 5 характеризуется как таящая наибольшие опасности. Я вынужден был
признать, что он меня "поймал".
Противоречие скорее лингвистическое, чем реальное. "Вторая" система,
описываемая в главе 5, - это вторая система, выпускаемая в развитие
предыдущей с привлечением дополнительных функций и украшений. "Вторая"
система в главе 11 - это вторая попытка разработки первой выпускаемой
системы. Она разрабатывается в условиях всех ограничений, накладываемых
графиком, способностями и неведением, характерными для новых проектов -
ограничений, навязывающих дисциплину умеренности.
Триумф интерфейса WIMP
Одним из наиболее впечатляющих явлений в программировании за последние
двадцать лет был триумф интерфейса, состоящего из окон, значков, меню и
указателей (Windows, Icons, Menus, Pointers - WIMP). Сегодня он настолько
широко известен, что не требует описания. Впервые эту идею представили
публике Дуг Энглебарт (Doug Englebart) с группой коллег из Стэндфордского
научно- исследовательского института на Объединенной компьютерной
конференции Запада в 1968 году.5 Оттуда идеи перекочевали в
исследовательский центр Xerox в Пало- Альто, где они реализовались на
персональной рабочей станции Alto, разработанной Бобом Тейлором (Bob Taylor)
с сотрудниками. Их подхватил Стив Джобс для компьютера Apple Lisa - слишком
медленного для осуществления своих восхитительных концепций простоты
использования. Эти концепции Джобс затем воплотил в коммерчески успешном
Apple Macintosh в 1985 году. Позднее они были приняты в Microsoft Windows
для IBM PC и его клонов. Мой пример будет базироваться на версии для Мака.6
Концептуальная целостность через метафору. WIMP является отличным
примером пользовательского интерфейса, обладающего концептуальной
целостностью, достигаемой принятием знакомой идеальной модели - метафоры
рабочего стола, и ее тщательного последовательного развития для
использования воплощения в компьютерной графике. Например, из принятой
метафоры непосредственно следует сложно осуществимое, но правильное решение
о перекрытии окон вместо расположения их одно рядом с другим. Возможность
менять размер и форму окон является последовательным расширением, дающим
пользователю новые возможности, обеспечиваемые носителем - компьютерной
графикой. У реальных бумаг на столе нельзя так же легко менять размер и
форму. Буксировка непосредственно вытекает из метафоры; выбор значков с
помощью курсора является прямой аналогией захвата предметов рукой. Значки и
вложенные папки являются точными аналогами документов на столе, как и
мусорная корзина. Идеи вырезания, копирования и вставки точно имитируют
операции, которые мы обычно осуществляем с документами на столе. Следование
метафоре столь буквально, а развитие настолько последовательно, что
пользователей-новичков решительно коробит, когда перетаскивание значка
дискеты в мусорную корзину приводит к извлечению дискеты из дисковода. Если
бы интерфейс не был столь единообразно последовательным, эта (довольно
неприятная) непоследовательность так бы не раздражала.
В каких местах интерфейс WIMP вынужден далеко отойти от метафоры
рабочего стола? Наиболее заметны два отличия: меню и работа одной рукой. На
реальном рабочем столе с документами осуществляют действия, а не приказывают
кому-то или чему-то осуществить их. А когда кому-то дается указание
совершить действие, команда обычно не выбирается из списка, а письменно или
устно подается в виде глагола в повелительном наклонении: "пожалуйста,
подшейте это в папку", "пожалуйста, найдите предыдущие письма" или
"пожалуйста, передайте это Мэри для принятия мер".
К сожалению, надежная интерпретация команд в свободном формате на
английском языке, будь они в устном или письменном виде, находится за
пределами наших сегодняшних возможностей. Поэтому проектировщики интерфейса
на два шага отошли от непосредственных действий пользователя с документами.
Они мудро взяли имевшийся на обычном рабочем столе образец выбора команд -
отпечатанную "сопроводиловку", в которой пользователь производит выбор из
ограниченного меню команд со стандартной семантикой. Эту идею они превратили
в горизонтальное меню с вертикально опускающимися подменю.
Подача команд и проблема двух курсоров. Команды являются повелительными
предложениями, в них всегда есть и обычно имеется прямое дополнение. Для
любого действия нужно задать глагол и существительное. Метафора указания
говорит, что для одновременного задания двух предметов нужно иметь на экране
два разных курсора, управляемых своими мышами, одной - в правой руке, другой
- в левой. В конце концов, на физическом столе мы обычно работаем двумя
руками. (Однако одна рука часто придерживает вещи на месте, что на
компьютерном рабочем столе происходит по умолчанию.) Мозг, конечно,
приспособлен к действиям двумя руками: мы систематически используем две руки
при вводе с клавиатуры, езде на автомобиле, приготовлении пищи. Увы, и одна
мышь была большим достижением для изготовителей компьютеров. Коммерческих
систем, поддерживающих одновременные действия с двумя курсорами мышей, по
одному для каждой руки, нет.7
Разработчики интерфейса смирились с реалиями и сделали проект для одной
мыши, приняв синтаксическое соглашение, что первым отмечается (выбирается)
существительное. Затем указывают на глагол, пункт меню. При этом в
значительной мере утрачивается простота использования. Когда я наблюдаю за
пользователями, просматриваю видеозапись их действий или зарегистрированные
компьютером перемещения курсора, то всегда обращаю внимание на то, что
одному курсору приходится выполнять работу двух: выбрать объект в окне на
рабочем столе; выбрать глагол в меню; найти другой объект или вновь отыскать
прежний; снова опустить меню (часто, то же самое) и выбрать глагол. Курсор
мечется взад-вперед, от пространства данных к пространству меню, всякий раз
теряя полезную информацию о том, где он находился в этом пространстве в
прошлый раз - в целом, неэффективный процесс.
Великолепное решение. Даже если бы электроника и программы могли без
труда работать одновременно с двумя активными курсорами, остаются сложности
с топологией пространства. На рабочем столе в метафоре WIMP в
действительности есть пишущая машинка, и в физическом пространстве реального
стола необходимо поместить реальную клавиатуру. Клавиатура плюс два коврика
для мышей займут немалую часть пространства в пределах досягаемости рук. Так
почему бы проблему клавиатуры не обратить себе на пользу, почему не
использовать обе руки - одной рукой задавая на клавиатуре глаголы, а другой
рукой выбирая существительные с помощью мыши? Теперь курсор будет оставаться
в пространстве данных и пользоваться тем, что последовательные
существительные выбираются близко одно от другого. Реальная эффективность,
реально большие возможности пользователя.
Мощность функций или простота использования. Однако при таком решении
теряется то, что делает использование меню таким простым для новичков: меню
представляет список альтернативных глаголов, допустимых в каждом конкретном
состоянии. Можно купить коробку, принести ее домой и начать работать, не
читаю инструкцию, зная лишь, для чего она куплена и экспериментируя с
различными глаголами в меню. Одна из сложнейших задач, стоящих перед
архитекторами - это найти соотношение между мощностью функций и простотой
использования. Нужно ли проектировать программу в расчете на новичка и
случайного пользователя или строить ее с мощными функциями для
профессионала? Идеальное решение - обеспечить и то, и другое концептуально
согласованным образом, что достигается при помощи интерфейса WIMP. У часто
используемых глаголов меню есть клавишные эквиваленты из одной клавиши +
командной клавиши, которые обычно легко ввести левой рукой одним аккордом.
Например, в Маке командная клавиша (^) находится как раз под клавишами Z и
X, поэтому самые частые действия кодируются как ^z, ^x, ^c, ^v, ^s.
Постепенный переход от новичка к опытному пользователю. Такая двойная
система задания командных глаголов не только отвечает потребности новичка в
легком обучении и потребности опытного пользователя в эффективном
использовании, но и позволяет каждому пользователю плавно перейти из одного
режима в другой. Буквенные обозначения, называемые клавишами сокращенного
набора, показываются в меню рядом с глаголами, поэтому в случае
неуверенности пользователь может раскрыть меню, чтобы проверить буквенный
эквивалент, вместо выбора пункта меню. Каждый новичок запоминает сначала
сокращенный набор для своих частых операций. Он может попробовать любое
сокращение, в котором не уверен, поскольку ^z отменяет любое ошибочное
одиночное действие. С другой стороны, он может справиться в меню
относительно допустимых команд. Новички очень часто опускают меню, опытные
пользователи - редко, а тем, которые находятся посередине, лишь от случая к
случаю понадобится выбирать из меню, поскольку они уже знают клавиши,
которые вызывают большинство осуществляемых ими операций. Мы, проектировщики
программного обеспечения, слишком привыкли к этому интерфейсу, чтобы оценить
его элегантность и мощь.
Успех прямого включения как средства навязывания архитектуры. Интерфейс
Мака примечателен еще в одном отношении. Без всякого принуждения
разработчики сделали его стандартом для разных приложений, включая
большинство из тех, которые описаны сторонними организациями. Поэтому
пользователь приобретает концептуальную согласованность на уровне интерфейса
не только для программ, поставляемых вместе с машиной, но и для всех других
приложений.
Этот подвиг создатели Мака осуществили, встроив интерфейс в ПЗУ, в
результате чего разработчикам проще и быстрее пользоваться существующим, чем
создавать свои идиосинкразические интерфейсы. Это естественное стремление к
единообразию возобладало настолько широко, что стало стандартом де-факто.
Естественные стремления были поддержаны полной приверженностью со стороны
менеджеров и существенным принуждением со стороны Apple. Независимые
рецензенты в журналах, поняв огромное значение межпрограммной концептуальной
целостности, также подкрепили естественные стремления, безжалостно критикуя
продукты, не удовлетворяющие этому интерфейсу.
Это отличительный пример технологии, рекомендованной в главе 6 для
достижения единообразия путем поощрения других сторон непосредственно
включать в свои продукты имеющийся код вместо разработки новых программ
согласно имеющимся спецификациям.
Судьба WIMP: устаревание. Несмотря на все достоинства, по моему мнению,
интерфейс WIMP через поколение станет достоянием истории. Указание курсором
останется способом задания существительных при управлении нашими
компьютерами. Для выражения глаголов станет использоваться речь. Такие
инструменты, как Voice Navigator для Маков и Dragon для PC, уже
предоставляют такую возможность.
Не разрабатывайте программ на выброс, каскадная модель неверна!
В главе 11 дается радикальный совет: "планируйте выбросить первую
программу, вам все равно придется это сделать". Сейчас я считаю это
ошибочным - не в силу чрезмерного радикализма, но в силу чрезмерной
упрощенности.
Самой большой ошибкой этой концепции является косвенное принятие
классической последовательности - в виде каскада - модели создания
программы. Эта модель происходит от структуры диаграммы Гранта для
поэтапного процесса, которую часто изображают, как на рисунке 19.1. В
классической статье 1970 года Винтон Ройс (Winton Royce) усовершенствовал
последовательную модель путем:
- добавления некоторой обратной связи с предшествующими этапами;
- ограничения обратной связи только непосредственными
предшественниками, чтобы исключить вызываемые ими издержки и задержки в
выполнении графика.
Он предвосхитил "МЧ-М", рекомендовав разработчикам "делать работу
дважды"8. Глава 11 - не единственная, на которую повлияла каскадная модель.
Она проходит через всю книгу, начиная с правила планирования в главе 2. Это
практическое правило отводит 1/3 времени на планирование, 1/6 - на написание
программ, 1/4 - на тестирование компонентов и 1/4 - на системное
тестирование.
Рис. 19.1 Каскадная модель создания программы
Основное заблуждение каскадной модели состоит в предположениях, что
проект проходит через весь процесс один раз, архитектура хороша и проста в
использовании, проект осуществления разумен, а ошибки в реализации
устраняются по мере тестирования. Иными словами, каскадная модель исходит из
того, что все ошибки будут сосредоточены в реализации, а потому их
устранение происходит равномерно во время тестирования компонентов и
системы.
"Планируйте на выброс" действительно резко нападает на это заблуждение.
Ошибка не в диагнозе, а в лекарстве. Сейчас я предположил, что первую
систему можно отбросить или перепроектировать не всю целиком, а по частям.
Хорошо, если это так, но при этом не затрагивается корень проблемы. В
каскадной модели системное тестирование, а следовательно и тестирование
пользователем, отодвигается в конец процесса создания программы. Поэтому
есть шанс обнаружить крайние неудобства для пользователя, или неприемлемые
технические характеристики, или опасную уязвимость к ошибкам или
злонамеренным действиям пользователя лишь в самом конце разработки. Изучение
спецификаций при альфа-тестировании нацелено на раннее обнаружение таких
ошибок, но ничто не может заменить непосредственных пользователей.
Вторым недостатком каскадной модели является предположение, что система
строится сразу вся целиком для тестирования с начала до конца после того,
как завершены все проектные разработки, большая часть написания программ и
значительная часть тестирования компонентов.
К несчастью, каскадная модель, это преобладавшее в 1975 году
представление о программных проектах, была включена в DOD-STD-2167 -
спецификацию Министерства обороны для любого военного программного
обеспечения. По этой причине она просуществовала долгое время после того,
как большая часть думающих практиков осознала ее неадекватность и отказалась
от нее. К счастью, в МО позднее поняли истину.9
Необходимо двигаться против течения. Опыт и идеи из каждой
расположенной ниже по течению части процесса создания программы, как
энергичный лосось, должны прыгать вверх по течению, иногда сразу через
несколько этапов, и воздействовать на деятельность наверху.
Проектные разработки покажут, что некоторые предусмотренные
архитектурой возможности ухудшают технические характеристики, и потому
архитектура должна быть переработана. Программирование при реализации
выявит, что некоторые функции непомерно увеличивают требования к памяти,
поэтому нужно внести изменения в архитектуру и разработку.
Поэтому вполне может потребоваться осуществить несколько итераций цикла
архитектура-разработка, прежде чем начать какую-либо программную реализацию.
Модель пошагового создания лучше: последовательное уточнение
Построение каркаса с начала до конца. Гарлан Миллз (Harlan Mills),
работающий в системе с разделением времени, давно уже рекомендует строить
основной цикл опроса системы реального времени с вызовами подпрограмм
(заглушками) для всех функций (рис. 19.2), но пустыми подпрограммами.
Откомпилируйте его, протестируйте, и он будет идти цикл за циклом, буквально
ничего не делая, но делая это без ошибок.10
Рис. 19.2
На следующем шаге мы навешиваем модуль ввода (возможно, примитивный) и
модуль вывода. Voila! Работающая система, делающая нечто, возможно,
неинтересное. Теперь, функция за функцией, мы строим и добавляем модули. На
каждом шаге мы имеем работающую систему. При достаточном трудолюбии на
каждом шаге мы имеем отлаженную, протестированную систему. (По мере роста
системы растет и тяжесть повторного тестирования всех новых модулей по всем
прежним контрольным примерам.)
После того как на примитивном уровне каждая функция работает, мы
улучшаем или переписываем один модуль за другим, пошагово наращивая систему.
Иногда для надежности мы переписываем исходный движущий цикл, а возможно, и
его интерфейсы с модулями.
Поскольку в любой момент времени у нас есть работающая система:
- можно очень рано начать тестирование пользователями;
- можно принять стратегию разработки в соответствии с бюджетом,
полностью защищающую от перерасхода времени или средств (возможно, за счет
сокращения функциональности).
В течение 22 лет я преподавал в лаборатории программной инженерии
Университета штата Северная Каролина, иногда вместе с Дэвидом Парнасом. На
этих занятиях бригады, обычно состоявшие из четырех человек, в течение
одного семестра должны были построить некоторую реальную прикладную
программную систему. Примерно посередине этого срока я стал преподавать
инкрементную разработку. Я был поражен, какой возбуждающий эффект на
моральный дух группы оказывает первая картинка на экране, первая работающая
система.
Семейства Парнаса. Дэвид Парнас был главным властителем дум в
программотехнике в течение всего этого 20-летнего периода. Всем известна его
идея скрытия информации. Менее известна очень важная идея Парнаса о
проектировании программного продукта как семейства взаимосвязанных
продуктов.11 Он требует, чтобы проектировщик имел в виду как дальнейшее
развитие, так и новые версии продукта и определял их функциональные или
межплатформенные различия так, чтобы строить дерево родственных продуктов
техническим характеристиками, размером, стоимостью и выполнением графика
работ. Выполнение этой задачи требует полной занятости, и только в очень
маленьких группах может быть совмещено с должностью руководителя.
Архитектора можно сравнивать с режиссером, а менеджера - с продюсером
кинокартины.
Отделение архитектуры от разработки и реализации. Чтобы сделать
возможным осуществление архитектором своей главной задачи, необходимо
отделить архитектуру, т.е. определение продукта в восприятии пользователя,
от его разработки. Архитектура и разработка определяют четкую грань между
разными частями задачи проектирования, и по каждую сторону этой грани лежит
большая работа.
Рекурсивность архитектуры. В очень больших проектах одному человеку не
справиться со всей архитектурой, даже если он избавлен от всех забот,
связанных с разработкой. Поэтому главный архитектор системы должен разбить
целое на подсистемы. Границы подсистем должны быть проведены так, чтобы
интерфейсы между ними были минимальны и легче всего строго определяемы.
Тогда у каждой части может быть свой архитектор, подчиняющийся главному
архитектору системы в отношении архитектуры. Очевидно, при необходимости
этот процесс может быть продолжен рекурсивно.
Сегодня я убежден более чем когда-либо. Концептуальная целостность
является важнейшим условием качества продукта. Наличие системного
архитектора есть важнейший шаг в направлении концептуальной целостности. Эти
принципы ни в коей мере не ограничиваются разработкой программного
обеспечения, а справедливы при проектировании любой сложной конструкции,
будь то компьютер, самолет, стратегическая оборонная инициатива или система
глобальной навигации. После преподавания в более чем 20 лабораториях
разработки программного обеспечения я стал настаивать, чтобы группы
учащихся, даже из четырех человек, выбирали менеджера и отдельно -
архитектора. Разделение функций в таких маленьких группах может показаться
несколько чрезмерным требованием, но, по моим наблюдениям, это оправдано и
способствует достижению успеха.
Эффект второй системы: функциональность и угадывание частоты
Проектирование для больших групп пользователей. Одним из последствий
революции, произведенной персональными компьютерами, является все
возрастающее, по крайней мере в области обработки деловых данных, вытеснение
заказных программ коробочными программными пакетами. Более того, стандартные
программные пакеты продаются сотнями тысяч и даже миллионами экземпляров.
Системные архитекторы программ, поставляемых вместе с машиной, всегда должны
были создавать проект, ориентированный на большую аморфную массу
пользователей, а не на отдельное определенное приложение в одной компании.
Теперь такая задача встает перед очень многими архитекторами.
Парадокс состоит в том, что спроектировать инструмент общего
назначения, нежели специализированный, гораздо труднее именно потому, что
нужно придать вес различающимся потребностям разных пользователей.
В погоне за функциональностью. Архитектор инструмента общего
назначения, такого, например, как электронная таблица или текстовый
редактор, подвержен сильному соблазну перегрузить продукт функциями
предельной полезности ценой снижения производительности и даже простоты
использования. Вначале привлекательность предлагаемых возможностей кажется
очевидной. Расплата производительностью становится очевидной лишь при
системном тестировании. Утрата простоты использования коварно подкрадывается
по мере того, как небольшими порциями добавляются новые функции, а
руководства пользователя все более разбухают.1
Соблазн особенно велик в отношении долгоживущих массовых продуктов,
развивавшихся на протяжении ряда поколений. Миллионы покупателей требуют
сотен новых возможностей. Всякая просьба свидетельствует о наличии спроса на
рынке. Часто архитектор первоначальной системы уже ушел в поход за новой
славой, и архитектура оказалась в руках людей с меньшим опытом взвешенного
представления общих интересов пользователей. В недавней рецензии на
Microsoft Word 6.0 сказано: "Переполнен возможностями; обновление замедлено
перегруженностью... Кроме того, Word 6.0 занимает много места и медленно
работает." С неудовольствием отмечается, что Word 6.0 занимает 4 Мбайт
памяти и сообщается, что из-за богатых дополнительных функциональных
возможностей "даже Macintosh IIfx едва пригоден для выполнения Word 6".2
Определение группы пользователей. Чем крупнее и аморфнее группа
предполагаемых пользователей, тем более необходимо явно ее определить, если
вы намерены достичь концептуальной целостности. У каждого члена группы
проектировщиков наверняка есть неявный мысленный образ пользователя, и все
образы будут отличаться друг от друга. Поскольку представление архитектора о
пользователе явно или подсознательно оказывает влияние на все архитектурные
решения, важно, чтобы команда проектировщиков пришла к единому общему
образу. Для этого необходимо составить список признаков предполагаемых
пользователей, указав в нем:
- кто они такие,
- что им нужно,
- что, по их мнению, им нужно,
- чего они хотят.
Частоты. Для любого программного продукта каждая характеристика
пользователя представляет собой распределение со множеством возможных
значений и соответствующими частотами. Как архитектору получить эти частоты?
Изучение этой слабо очерченной популяции представляется сомнительным и
дорогостоящим занятием.3 С годами я пришел к убеждению, что архитектор
должен угадать или, если вам больше нравится, постулировать полный набор
признаков и значений вместе с частотами для создания полного, явного и
общего для всех описания группы пользователей.
Такая непривлекательная процедура имеет ряд полезных последствий.
Во-первых, при стремлении точно угадать частоты архитектор вынужден очень
тщательно обдумать, какова возможная группа пользователей. Во-вторых, при
фиксации частот возникает обсуждение, полезное для всех участников и
выявляющее различия в образах пользователя, имеющихся у разных
проектировщиков. В-третьих, явное присвоение частот содействуют пониманию
того, какие решения какими свойствами группы пользователей обусловлены. Даже
такой неформальный анализ чувствительности приносит пользу. Когда
обнаруживается, что очень важные решения зависят от некоторых специфических
предположений, оказывается уместным получить более точные численные оценки.
(Разработанная Джеффом Конклином (Jeff Conklin) система позволяет формально
и точно прослеживать принятие проектных решений и документировать их
основания.4 Мне не приходилось ею пользоваться, но думаю, что она должна
быть очень полезна.)
Подводя итоги: установите предположительные признаки группы
пользователей. Гораздо лучше ошибаться, но выражаться ясно, чем выражаться
туманно.
Как насчет эффекта второй системы? Один наблюдательный ученый заметил,
что "Мифический человеко-месяц" рекомендовал на случай неудачи для всякой
новой системы планировать поставку второй версии (см. глава 11), которая в
главе 5 характеризуется как таящая наибольшие опасности. Я вынужден был
признать, что он меня "поймал".
Противоречие скорее лингвистическое, чем реальное. "Вторая" система,
описываемая в главе 5, - это вторая система, выпускаемая в развитие
предыдущей с привлечением дополнительных функций и украшений. "Вторая"
система в главе 11 - это вторая попытка разработки первой выпускаемой
системы. Она разрабатывается в условиях всех ограничений, накладываемых
графиком, способностями и неведением, характерными для новых проектов -
ограничений, навязывающих дисциплину умеренности.
Триумф интерфейса WIMP
Одним из наиболее впечатляющих явлений в программировании за последние
двадцать лет был триумф интерфейса, состоящего из окон, значков, меню и
указателей (Windows, Icons, Menus, Pointers - WIMP). Сегодня он настолько
широко известен, что не требует описания. Впервые эту идею представили
публике Дуг Энглебарт (Doug Englebart) с группой коллег из Стэндфордского
научно- исследовательского института на Объединенной компьютерной
конференции Запада в 1968 году.5 Оттуда идеи перекочевали в
исследовательский центр Xerox в Пало- Альто, где они реализовались на
персональной рабочей станции Alto, разработанной Бобом Тейлором (Bob Taylor)
с сотрудниками. Их подхватил Стив Джобс для компьютера Apple Lisa - слишком
медленного для осуществления своих восхитительных концепций простоты
использования. Эти концепции Джобс затем воплотил в коммерчески успешном
Apple Macintosh в 1985 году. Позднее они были приняты в Microsoft Windows
для IBM PC и его клонов. Мой пример будет базироваться на версии для Мака.6
Концептуальная целостность через метафору. WIMP является отличным
примером пользовательского интерфейса, обладающего концептуальной
целостностью, достигаемой принятием знакомой идеальной модели - метафоры
рабочего стола, и ее тщательного последовательного развития для
использования воплощения в компьютерной графике. Например, из принятой
метафоры непосредственно следует сложно осуществимое, но правильное решение
о перекрытии окон вместо расположения их одно рядом с другим. Возможность
менять размер и форму окон является последовательным расширением, дающим
пользователю новые возможности, обеспечиваемые носителем - компьютерной
графикой. У реальных бумаг на столе нельзя так же легко менять размер и
форму. Буксировка непосредственно вытекает из метафоры; выбор значков с
помощью курсора является прямой аналогией захвата предметов рукой. Значки и
вложенные папки являются точными аналогами документов на столе, как и
мусорная корзина. Идеи вырезания, копирования и вставки точно имитируют
операции, которые мы обычно осуществляем с документами на столе. Следование
метафоре столь буквально, а развитие настолько последовательно, что
пользователей-новичков решительно коробит, когда перетаскивание значка
дискеты в мусорную корзину приводит к извлечению дискеты из дисковода. Если
бы интерфейс не был столь единообразно последовательным, эта (довольно
неприятная) непоследовательность так бы не раздражала.
В каких местах интерфейс WIMP вынужден далеко отойти от метафоры
рабочего стола? Наиболее заметны два отличия: меню и работа одной рукой. На
реальном рабочем столе с документами осуществляют действия, а не приказывают
кому-то или чему-то осуществить их. А когда кому-то дается указание
совершить действие, команда обычно не выбирается из списка, а письменно или
устно подается в виде глагола в повелительном наклонении: "пожалуйста,
подшейте это в папку", "пожалуйста, найдите предыдущие письма" или
"пожалуйста, передайте это Мэри для принятия мер".
К сожалению, надежная интерпретация команд в свободном формате на
английском языке, будь они в устном или письменном виде, находится за
пределами наших сегодняшних возможностей. Поэтому проектировщики интерфейса
на два шага отошли от непосредственных действий пользователя с документами.
Они мудро взяли имевшийся на обычном рабочем столе образец выбора команд -
отпечатанную "сопроводиловку", в которой пользователь производит выбор из
ограниченного меню команд со стандартной семантикой. Эту идею они превратили
в горизонтальное меню с вертикально опускающимися подменю.
Подача команд и проблема двух курсоров. Команды являются повелительными
предложениями, в них всегда есть и обычно имеется прямое дополнение. Для
любого действия нужно задать глагол и существительное. Метафора указания
говорит, что для одновременного задания двух предметов нужно иметь на экране
два разных курсора, управляемых своими мышами, одной - в правой руке, другой
- в левой. В конце концов, на физическом столе мы обычно работаем двумя
руками. (Однако одна рука часто придерживает вещи на месте, что на
компьютерном рабочем столе происходит по умолчанию.) Мозг, конечно,
приспособлен к действиям двумя руками: мы систематически используем две руки
при вводе с клавиатуры, езде на автомобиле, приготовлении пищи. Увы, и одна
мышь была большим достижением для изготовителей компьютеров. Коммерческих
систем, поддерживающих одновременные действия с двумя курсорами мышей, по
одному для каждой руки, нет.7
Разработчики интерфейса смирились с реалиями и сделали проект для одной
мыши, приняв синтаксическое соглашение, что первым отмечается (выбирается)
существительное. Затем указывают на глагол, пункт меню. При этом в
значительной мере утрачивается простота использования. Когда я наблюдаю за
пользователями, просматриваю видеозапись их действий или зарегистрированные
компьютером перемещения курсора, то всегда обращаю внимание на то, что
одному курсору приходится выполнять работу двух: выбрать объект в окне на
рабочем столе; выбрать глагол в меню; найти другой объект или вновь отыскать
прежний; снова опустить меню (часто, то же самое) и выбрать глагол. Курсор
мечется взад-вперед, от пространства данных к пространству меню, всякий раз
теряя полезную информацию о том, где он находился в этом пространстве в
прошлый раз - в целом, неэффективный процесс.
Великолепное решение. Даже если бы электроника и программы могли без
труда работать одновременно с двумя активными курсорами, остаются сложности
с топологией пространства. На рабочем столе в метафоре WIMP в
действительности есть пишущая машинка, и в физическом пространстве реального
стола необходимо поместить реальную клавиатуру. Клавиатура плюс два коврика
для мышей займут немалую часть пространства в пределах досягаемости рук. Так
почему бы проблему клавиатуры не обратить себе на пользу, почему не
использовать обе руки - одной рукой задавая на клавиатуре глаголы, а другой
рукой выбирая существительные с помощью мыши? Теперь курсор будет оставаться
в пространстве данных и пользоваться тем, что последовательные
существительные выбираются близко одно от другого. Реальная эффективность,
реально большие возможности пользователя.
Мощность функций или простота использования. Однако при таком решении
теряется то, что делает использование меню таким простым для новичков: меню
представляет список альтернативных глаголов, допустимых в каждом конкретном
состоянии. Можно купить коробку, принести ее домой и начать работать, не
читаю инструкцию, зная лишь, для чего она куплена и экспериментируя с
различными глаголами в меню. Одна из сложнейших задач, стоящих перед
архитекторами - это найти соотношение между мощностью функций и простотой
использования. Нужно ли проектировать программу в расчете на новичка и
случайного пользователя или строить ее с мощными функциями для
профессионала? Идеальное решение - обеспечить и то, и другое концептуально
согласованным образом, что достигается при помощи интерфейса WIMP. У часто
используемых глаголов меню есть клавишные эквиваленты из одной клавиши +
командной клавиши, которые обычно легко ввести левой рукой одним аккордом.
Например, в Маке командная клавиша (^) находится как раз под клавишами Z и
X, поэтому самые частые действия кодируются как ^z, ^x, ^c, ^v, ^s.
Постепенный переход от новичка к опытному пользователю. Такая двойная
система задания командных глаголов не только отвечает потребности новичка в
легком обучении и потребности опытного пользователя в эффективном
использовании, но и позволяет каждому пользователю плавно перейти из одного
режима в другой. Буквенные обозначения, называемые клавишами сокращенного
набора, показываются в меню рядом с глаголами, поэтому в случае
неуверенности пользователь может раскрыть меню, чтобы проверить буквенный
эквивалент, вместо выбора пункта меню. Каждый новичок запоминает сначала
сокращенный набор для своих частых операций. Он может попробовать любое
сокращение, в котором не уверен, поскольку ^z отменяет любое ошибочное
одиночное действие. С другой стороны, он может справиться в меню
относительно допустимых команд. Новички очень часто опускают меню, опытные
пользователи - редко, а тем, которые находятся посередине, лишь от случая к
случаю понадобится выбирать из меню, поскольку они уже знают клавиши,
которые вызывают большинство осуществляемых ими операций. Мы, проектировщики
программного обеспечения, слишком привыкли к этому интерфейсу, чтобы оценить
его элегантность и мощь.
Успех прямого включения как средства навязывания архитектуры. Интерфейс
Мака примечателен еще в одном отношении. Без всякого принуждения
разработчики сделали его стандартом для разных приложений, включая
большинство из тех, которые описаны сторонними организациями. Поэтому
пользователь приобретает концептуальную согласованность на уровне интерфейса
не только для программ, поставляемых вместе с машиной, но и для всех других
приложений.
Этот подвиг создатели Мака осуществили, встроив интерфейс в ПЗУ, в
результате чего разработчикам проще и быстрее пользоваться существующим, чем
создавать свои идиосинкразические интерфейсы. Это естественное стремление к
единообразию возобладало настолько широко, что стало стандартом де-факто.
Естественные стремления были поддержаны полной приверженностью со стороны
менеджеров и существенным принуждением со стороны Apple. Независимые
рецензенты в журналах, поняв огромное значение межпрограммной концептуальной
целостности, также подкрепили естественные стремления, безжалостно критикуя
продукты, не удовлетворяющие этому интерфейсу.
Это отличительный пример технологии, рекомендованной в главе 6 для
достижения единообразия путем поощрения других сторон непосредственно
включать в свои продукты имеющийся код вместо разработки новых программ
согласно имеющимся спецификациям.
Судьба WIMP: устаревание. Несмотря на все достоинства, по моему мнению,
интерфейс WIMP через поколение станет достоянием истории. Указание курсором
останется способом задания существительных при управлении нашими
компьютерами. Для выражения глаголов станет использоваться речь. Такие
инструменты, как Voice Navigator для Маков и Dragon для PC, уже
предоставляют такую возможность.
Не разрабатывайте программ на выброс, каскадная модель неверна!
В главе 11 дается радикальный совет: "планируйте выбросить первую
программу, вам все равно придется это сделать". Сейчас я считаю это
ошибочным - не в силу чрезмерного радикализма, но в силу чрезмерной
упрощенности.
Самой большой ошибкой этой концепции является косвенное принятие
классической последовательности - в виде каскада - модели создания
программы. Эта модель происходит от структуры диаграммы Гранта для
поэтапного процесса, которую часто изображают, как на рисунке 19.1. В
классической статье 1970 года Винтон Ройс (Winton Royce) усовершенствовал
последовательную модель путем:
- добавления некоторой обратной связи с предшествующими этапами;
- ограничения обратной связи только непосредственными
предшественниками, чтобы исключить вызываемые ими издержки и задержки в
выполнении графика.
Он предвосхитил "МЧ-М", рекомендовав разработчикам "делать работу
дважды"8. Глава 11 - не единственная, на которую повлияла каскадная модель.
Она проходит через всю книгу, начиная с правила планирования в главе 2. Это
практическое правило отводит 1/3 времени на планирование, 1/6 - на написание
программ, 1/4 - на тестирование компонентов и 1/4 - на системное
тестирование.
Рис. 19.1 Каскадная модель создания программы
Основное заблуждение каскадной модели состоит в предположениях, что
проект проходит через весь процесс один раз, архитектура хороша и проста в
использовании, проект осуществления разумен, а ошибки в реализации
устраняются по мере тестирования. Иными словами, каскадная модель исходит из
того, что все ошибки будут сосредоточены в реализации, а потому их
устранение происходит равномерно во время тестирования компонентов и
системы.
"Планируйте на выброс" действительно резко нападает на это заблуждение.
Ошибка не в диагнозе, а в лекарстве. Сейчас я предположил, что первую
систему можно отбросить или перепроектировать не всю целиком, а по частям.
Хорошо, если это так, но при этом не затрагивается корень проблемы. В
каскадной модели системное тестирование, а следовательно и тестирование
пользователем, отодвигается в конец процесса создания программы. Поэтому
есть шанс обнаружить крайние неудобства для пользователя, или неприемлемые
технические характеристики, или опасную уязвимость к ошибкам или
злонамеренным действиям пользователя лишь в самом конце разработки. Изучение
спецификаций при альфа-тестировании нацелено на раннее обнаружение таких
ошибок, но ничто не может заменить непосредственных пользователей.
Вторым недостатком каскадной модели является предположение, что система
строится сразу вся целиком для тестирования с начала до конца после того,
как завершены все проектные разработки, большая часть написания программ и
значительная часть тестирования компонентов.
К несчастью, каскадная модель, это преобладавшее в 1975 году
представление о программных проектах, была включена в DOD-STD-2167 -
спецификацию Министерства обороны для любого военного программного
обеспечения. По этой причине она просуществовала долгое время после того,
как большая часть думающих практиков осознала ее неадекватность и отказалась
от нее. К счастью, в МО позднее поняли истину.9
Необходимо двигаться против течения. Опыт и идеи из каждой
расположенной ниже по течению части процесса создания программы, как
энергичный лосось, должны прыгать вверх по течению, иногда сразу через
несколько этапов, и воздействовать на деятельность наверху.
Проектные разработки покажут, что некоторые предусмотренные
архитектурой возможности ухудшают технические характеристики, и потому
архитектура должна быть переработана. Программирование при реализации
выявит, что некоторые функции непомерно увеличивают требования к памяти,
поэтому нужно внести изменения в архитектуру и разработку.
Поэтому вполне может потребоваться осуществить несколько итераций цикла
архитектура-разработка, прежде чем начать какую-либо программную реализацию.
Модель пошагового создания лучше: последовательное уточнение
Построение каркаса с начала до конца. Гарлан Миллз (Harlan Mills),
работающий в системе с разделением времени, давно уже рекомендует строить
основной цикл опроса системы реального времени с вызовами подпрограмм
(заглушками) для всех функций (рис. 19.2), но пустыми подпрограммами.
Откомпилируйте его, протестируйте, и он будет идти цикл за циклом, буквально
ничего не делая, но делая это без ошибок.10
Рис. 19.2
На следующем шаге мы навешиваем модуль ввода (возможно, примитивный) и
модуль вывода. Voila! Работающая система, делающая нечто, возможно,
неинтересное. Теперь, функция за функцией, мы строим и добавляем модули. На
каждом шаге мы имеем работающую систему. При достаточном трудолюбии на
каждом шаге мы имеем отлаженную, протестированную систему. (По мере роста
системы растет и тяжесть повторного тестирования всех новых модулей по всем
прежним контрольным примерам.)
После того как на примитивном уровне каждая функция работает, мы
улучшаем или переписываем один модуль за другим, пошагово наращивая систему.
Иногда для надежности мы переписываем исходный движущий цикл, а возможно, и
его интерфейсы с модулями.
Поскольку в любой момент времени у нас есть работающая система:
- можно очень рано начать тестирование пользователями;
- можно принять стратегию разработки в соответствии с бюджетом,
полностью защищающую от перерасхода времени или средств (возможно, за счет
сокращения функциональности).
В течение 22 лет я преподавал в лаборатории программной инженерии
Университета штата Северная Каролина, иногда вместе с Дэвидом Парнасом. На
этих занятиях бригады, обычно состоявшие из четырех человек, в течение
одного семестра должны были построить некоторую реальную прикладную
программную систему. Примерно посередине этого срока я стал преподавать
инкрементную разработку. Я был поражен, какой возбуждающий эффект на
моральный дух группы оказывает первая картинка на экране, первая работающая
система.
Семейства Парнаса. Дэвид Парнас был главным властителем дум в
программотехнике в течение всего этого 20-летнего периода. Всем известна его
идея скрытия информации. Менее известна очень важная идея Парнаса о
проектировании программного продукта как семейства взаимосвязанных
продуктов.11 Он требует, чтобы проектировщик имел в виду как дальнейшее
развитие, так и новые версии продукта и определял их функциональные или
межплатформенные различия так, чтобы строить дерево родственных продуктов