азин и купить уже готовым то, что они собираются разработать. Это не шутка: доступность дешевых и мощных коробочных программ удовлетворила многие из потребностей, ранее удовлетворявшихся заказными программами. Эти электроинструменты для ума больше похожи на электрическте дрели, пилы и шлифовальные машины, чем на большие и сложные производственные станки. Интеграция их в совместимые и перекрестно-связанные наборы, такие как Microsoft Works или лучше интегрированный ClarisWorks, обеспечивает огромную гибкость. И подобно домашней коллекции инструмента, в результате частого использования набольшого набора для разных задач вырабатываются привычные навыки. Такой инструмент подчеркивает простоту использования обычным пользователем, даже не профессионалом. Иван Селин (Ivan Selin), глава American Management Systems писал мне в 1987 году: Я хочу придраться к вашему утверждению, что в действительности пакеты не настолько изменились... Я думаю, что вы слишком легко отбросили главные следствия вашего замечания, что (программные пакеты) "могут быть немного более общими и немного лучше настраиваемыми, чем раньше, но не намного". Даже принимая это заявление за чистую монету, я полагаю, что пользователи расценивают пакеты, как обладающие более широкими возможностями и легче настраиваемые, и что такое восприятие делает пользователей более податливыми перед пакетами. В большинстве случаев, известных моей компании, не программисты, а (конечные) пользователи неохотно пользуются пакетами, покскольку думают, что лишатся важных возможностей и функций, а потому возможность легкой настройки весьма повышает для них привлекательность продукта. Я думаю, что Селин совершенно прав: я недооценил как степень настраиваемости пакета, так и важность этого фактора. Объектно-ориентированное программирование: а медна пуля не подойдет? Разработка из больших частей. Если осуществлять сборку из частей, которые достаточно сложны и имеют однородные интерфейсы, можно быстро образовывать довольно богатые структуры. Согласно одному из взглядов на объектно-ориентированное программирование эта дисциплина осуществляет модульность и чистые интерфейсы. Другая точка зрения подчеркивает инкапсуляцию - невозможность увидеть и еще менее изменить внутреннюю структуру детали. Еще одна точка зрения отмечает наследование и сопутствующую ему иерархическую структуру классов с виртуальными функциями. И еще один взгляд: важнейшей является сильная абстрактная типизация данных вместе с гарантиями, что конкретный тип данных будет обрабатываться только применимыми к нему операциями. В настоящее время не нужен весь пакет Smalltalk или C++, чтобы использовать любой из этих дисциплин - многие из них поглотили объектно-ориентированные технологии. Объектно-ориентированный подход привлекателен, как поливитамины: одним махом (т.е. переподготовкой программиста) получаешь все. Очень многообещающая концепция. Почему объектно-ориентированная технология медленно развивалась? В течение девяти лет после выхода "СПН" надежды неуклонно росли. Почему развитие было таким медленным? Теорий много. Джеймс Коггинс, в течение четырех лет ведущий колонку в The C++ Report, дает такое объяснение: Проблема в том, что программисты, работающие в ООП, экспериментировали с кровосмесительными приложениями и были нацелены на низкий уровень абстракции. Например, они строили такие классы, как "связанный список" вместо "интерфейс пользователя", или "луч радиации", или "модель из конечных элементов". К несчастью, строгая проверка типов, которая помогает программистам C++ избегать ошибок, одновременно затрудняет построение больших объектов из маленьких.21 Он возвращается к фундаментальной проблеме программирования и доказывает, что один из способов удовлетворить потребность в программном обеспечении - увеличить численность образованной рабочей силы путем подготовки и привлечения наших клиентов. В пользу нисходящего проектирования приводятся такие аргументы: Если мы проектируем крупные классы, представляющие концепции, с которыми наши клиенты уже работают, то они в состоянии понимать и критиковать проект по мере его развития, а также вместе с нами разрабатывать контрольные примеры. Офтальмологов, с которыми я работаю, не волнует организация стека; их волнует описание формы роговицы с помощью полиномов Лежандра. Маленькая инкапсуляция дает и маленькую выгоду. Дэвид Парнас, чья статья была одним из источников идей объектно- ориентированного программирования, смотрят на вещи по иному. Он писал мне: Ответ прост. Это из-за привязанности ООП к сложным языкам. Вместо объяснения людям, что ООП является видом проектирования, и вооружения их принципами проектирования, их учили, что ООП - это использование определенного инструмента. Любыми срадствами можно писать и плохие, и хорошие программы. Если не учить людей проектированию, то языки не имеют большого значения. Результатом будут плохие разработки с помощью этих языков и малая выгода. А если выгода невелика, то ООП не войдет в моду. Расходы сейчас, прибыль потом. По моему мнению, у объектно-ориентированных методологий особенно тяжелый случай болезни, характерной для многих усовершенствований в методологии. Весьма существенны предварительные издержки - в основном, чтобы научить программистов мыслить совершенно по новому, а также на преобразование функций в обобщенные классы. Выгоды, которые я считаю реальными, а не чисто предположительными, достигаются во время всего цикла разработки, но настоящая окупаемость происходит при разработке последующих программ, расширении и сопровождении. Коггинс коворит: "Объектно-ориентированное программирование не ускорит разработку первого проекта, так же как и второго. А вот пятый проект из того же семейства будет сделан очень быстро."22 Рисковать реальными начальными деньгами ради предполагаемых, но неопределенных прибылей в будущем - это то, чем инвесторы занимаются изо дня в день. Однако во многих программирующих организациях менеджерам требуется для этого смелость - качество более редкое, чем компетенция в технических вопросах или административное мастерство. Я полагаю, что крайняя степень авансироания расходов и откладывания прибыли является самым существенным фактором, замедляющим принятие О-О технологий. Но даже в таких условиях C++, похоже, уверенно вытесняет C во многих организациях. Что с повторным использованием? Лучший способ справиться с разработкой части программной системы, относящейся к ее сущности - это вообще ее не разрабатывать. Пакеты программ - один из способов сделать это. Другой способ - повторное использование. Действительно, одной из наиболее привлекательных черт объектно-ориентированного программирования является обещание простоты повторного использования классов в сочетании с легкостью настройки благодаря наследованию. Как часто бывает, после получения некоторого опыта работы по новой технологии обнаруживается, что она не так проста, как казалось на первый взгляд. Конечно, программисты всегда повторно использовали собственные разработки. Джонс пишет: У наиболее опытных программистов есть свои личные библиотеки, позволяющие им при разработке новых программ повторно использовать до 30% кода по объему. На корпоративном уровне повторное использование приближается к 75% по объему и требует специальных библиотек и администрирования. Повторное использование кода в корпоративных масштабах требует изменений в бухгалтерии проекта и методах измерения работы.23 У. Хуан (W. Huang) предложил организацию программного производства с матричной структурой управления функциональными специалистами, чтобы держать под контролем их естественную склонность к повторному использованию собственного кода.24 Ван Шнайдер (Van Snyder) из JPL напоминает мне, что в кругах разработчиков математического программного обеспечения существует давняя традиция повторного использования программ: Мы полагаем, что препятствия к повторному использованию возникают не со стороны производителя, а со стороны потребителя. Если разработчик программного обеспечения - потенциальный потребитель стандартных программных компонентов - считает, что найти и проверить нужный компонент дороже, чем написать его заново, значит, будет написан новый компонент, дублирующий прежний. Обратите внимание, мы сказали "считает" - реальная стоимость повторной разработки не имеет значения. Повторное использование кода имеет успех при разработке математических программ. Причин этому две: 1) это магия, требующая огромного интеллектуального вклада в каждую строчку кода, и 2) существует богатая и стандартная терминология, а именно - математика, для описания функциональности любых компонентов. Поэтому повторно разработать математический компонент стоит дорого, а разобраться в функциональности стоит дешево. Давняя традиция публикации и сбора алгоритмов профессиональными журналами и предложения их по умеренной цене, а также коммерческое предложение высококачественных алгоритмов по несколько более высокой, но все же скромной цене, делают поиск требуемых компонентов проще, чем в других областях, где часто невозможно точно и сжато описать требуемое. Благодаря совместному действию этих факторов повторное использование математических программ более привлекательно, чем повторное их изобретение. Такое же явление повторного использования обнаруживается и в других сообществах, например, в разработке программ для атомных реакторов, моделирования климата, моделирования океанов - по тем же самым причинам. Каждое из этих сообществ выросло на одних и тех же учебниках, с одной и той же системой обозначений. Как сегодня обстоят дела с повторным использованием на корпоративном уровне? Проведено множество исследований, а вот практикуется в США относительно мало. Что же касается повторного использования за рубежом, то тут имеют место неправдоподобные отчеты.25 Джонс сообщает, что все клиенты его фирмы, у которых более 5000 программистов, проводят формальные исследования повторной используемости, в то время как из числа клиентов с 500 и менее программстами это делает менее 10 процентов.26 По его сообщению, в отраслях с высоким потенциалом повторного использования исследования (не реализация) "ведутся активно и энергично, даже если не вполне успешно". Эд Йордон сообщает о программной фирме в Маниле, в которой 50 программистов из общего числа 200 заняты только разработкой повторно используемых модулей для использования всеми остальными, и что в тех случаях, которые он видел, принятие этой технологии было вызвано организационными, а не техническими факторами - например, системой поощрений. Демарко сообщает мне, что наличие массовых рыночных пакетов и возможность предоставления ими общих функций, таких как системы баз данных, существенно снизили как настоятельность, так и предельную полезность повторного использования модулей собственных приложений. "Повторно используемые модули имели тенденцию в конце концов становиться общими функциями." Парнас пишет следующее: Повторное использование - это то, о чем легче говорить, чем осуществить. Для него требуются как хорошее проектирование, так и очень хорошая документация. Даже когда мы видим хорошее проектирование, что по- прежнему не часто, без хорошей документации компоненты не будут использоваться повторно. Кен Брукс сообщает, что трудно рассчитать, какая степень обобщенности окажется необходимой: "Мне приходится менять вещи, даже в пятый раз используя собственную библиотеку пользовательских интерфейсов." Реально повторное использование только начинается. Джонс сообщает, что на открытом рынке есть несколько модулей с повторно используемым кодом по цене от 1 до 20 процентов от обычной стоимости разработки.27 Демарко говорит: Меня все более обескураживает вся эта история с повторным использованием. Практически отсутствует теорема существования для повторного использования. Время подтвердило, что сделать вещи повторно используемыми стоит дорого. Йордон дает оценку того, сколько это стоит: "Хорошее эмпирическое правило говорит, что повторно используемые компоненты потребуют вдвое больших затрат, чем "одноразовые" компоненты."28 Я рассматриваю эту цену как величину затрат на запуск компонентов в производство, обсуждавшуюся в главе 1, поэтому я оцениваю рост затрат как троекратный. Конечно, мы видим различные формы и варианты повторного использования, но оно далеко не так широко применяется, как мы предполагали. Предстоит еще многое понять. Понимание больших словарей: неожиданная проблема повторного использования, которую можно было предвидеть Чем выше уровень, на котором осуществляется мышление, тем более многочисленны примитивные составляющие мысли, с которыми приходится иметь дело. Так, языки высокого уровня гораздо сложнее машинных языков, а естественные языки еще более сложны. У языков высокого уровня больше словари, более сложный синтаксис и более строгая семантика. Как научная дисциплина, мы не взвесили последствия этого факта для повторного использования программ. Чтобы повысить качество и производительность, мы хотим строить программы из частей с отлаженными функциями, которые существенно выше по уровню, чем операторы языков программирования. Поэтому, делаем ли мы это с помощью библиотек классов или библиотек процедур, нам придется столкнуться с резким увеличением размеров наших словарей программирования. Изучение словаря составляет значительную часть препятствий к повторному использованию. На сегодняшний день есть библиотеки классов, насчитывающие свыше 3000 членов. Многие объекты требуют задания от 10 до 20 параметров и переменных- переключателей. Всякий, использующий такую библиотеку, должен изучить синтаксис (внешние интерфейсы) и семантику (подробное поведение функции) ее членов, если собирается полностью реализовать потенциал повторного использования. Эта задача вовсе не безнадежна. Обычно человек использует около 10000 слов родного языка, образованные люди - значительно больше. Каким-то образом мы обучаемся синтаксису и тонким семантическим различиям. Мы правильно опеределяем различия между словами гигантский, огромный, пространный, колоссальный, громадный - никто не говорит о колоссальных пустынях и пространных слонах. Нужны дополнительные исследования, чтобы можно было применить к проблеме повторного использования программ существующие знания о том, как люди овладевают языком. Некоторые выводы непосредственно очевидны: - Обучение происходит в контексте предложения, поэтому нужно публиковать многочисленные примеры составных продуктов, а не просто библиотеки составляющих частей. - Человек запоминает только правописание. Синтаксис и семантика изучаются постепенно, в контексте, путем применения. - Человек группирует правила соединения слов в синтаксические классы, а не в совместимые подмножества объектов. Чистый итог по пулям: положение прежнее Итак, мы возвращаемся к основам. Сложность - это то, чем мы занимаемся, и сложность - это то, что нас ограничивает. Р. Л. Гласс (R. L. Glass) писал в 1988 году, точно суммируя мои взгляды 1995 года: Так что же в итоге сообщили нам Парнас и Брукс? Что разработка программ является концептуально сложным занятием. Что волшебные решения не лежат за каждым углом. Что занимающимся этим делом пора изучить достижения, имеющие эволюционный характер, а не ждать революцию и не надеяться на нее. Некоторые считают это безрадостной картиной. Это те, кто полагал, что вот-вот наступит прорыв. Но некоторые из нас - достаточно сварливые, чтобы считать себя реалистами, - относятся к этому как к глотку свежего воздуха. Наконец-то можно сосредоточиться на чем-то более близком к жизни, чем журавль в небе. Теперь, вероятно, мы сможем заняться постепенными усовершенствованиями производства программного обеспечения, которые действительно достижимы, а не ждать прорывов, которые вряд ли когда-либо произойдут.29 Глава 18. Заявления "Мифического человеко-месяца": правда или ложь? Краткость очень полезна, Когда нас понимают или не понимают. СЭМЮЭЛ БАТЛЕР, "ГУДИБРАС" Сегодня о технике разработки программного обеспечения известно значительно больше, чем в 1975 году. Какие из утверждений, содержащихся в первом издании 1975 года, подтвердились опытом и данными? Какие были опровергнуты? Какие устарели в нашем изменчивом мире? Чтобы вам легче было судить, здесь, в виде сводки, приведены важнейшие утверждения книги 1975 года, которые я считал верными: факты и извлеченные из опыта практические правила, приведенные с сохранением изначального смысла. (Можно задаться вопросом: если это все, что было сказано в первоначальном издании, почему тогда это заняло так много места?) В скобках приведены свежие комментарии. Большинство этих предложений можно проверить на практике. Излагая их в сжатой форме, я надеюсь сконцентрировать мысли читателя, измерения и комментарии. Глава 1. Смоляная яма 1.1 Для создания системного программного продукта требуется примерно в девять раз больше усилий по сравнению с составляющими его программами, написанными отдельно для частного использования. По моей оценке, превращение программы в продукт вводит коэффициент, равный трем; проектирование, интеграция и тестирование компонентов, которые должны образовать согласованную систему, также вводит коэффициент, равный трем; все эти составляющие стоимости существенно независимы друг от друга. 1.2 Занятие программированием "отвечает глубокой внутренней потребности в творчестве и удовлетворяет чувственные потребности, которые есть у всех у нас", доставляя пять видов радости: - Радость, получаемая при создании чего-либо своими руками. - Удовольствие создавать вещи, которые могут быть полезны другим людям. - Очарование создания сложных головоломных объектов, состоящих из взаимодействующих движущихся частей. - Радость, получаемая от неизменного узнавания нового, неповторяемости задачи. - Удовольствие от работы со столь податливым материалом - чистой мыслью, который, тем не менее, существует, движется и работает так, как не могут словесные объекты. 1.3 В то же время этому занятию присущи и огорчения: - При изучении программирования труднее всего привыкнуть к требованию совершенства. - Постановка задач осуществляется другими людьми и приходится зависеть от вещей (особенно, программ), которые нельзя контролировать; полномочия не соответствуют ответственности. - Страшно только на словах: фактическая власть приобретается как следствие успешного выполнения задач. - Программный проект приближается к окончательному виду тем медленнее, чем ближе окончание, хотя кажется, что к концу сходимость должна быть более быстрой. - Программному продукту грозит устаревание еще до его завершения. Настоящий тигр - не пара бумажному, если требуется реальное использование. Глава 2. Мифический человеко-месяц 2.1 Программные проекты чаще проваливаются из-за нехватки календарного времени, чем по всем остальным причинам, вместе взятым. 2.2 Чтобы приготовить вкусную пищу, нужно время; некоторые задачи нельзя ускорить, не испортив результат. 2.3 Все программисты являются оптимистами: "Все будет хорошо". 2.4 Поскольку программист работает с чистыми идеями, мы не ожидаем особых трудностей при реализации. 2.5 Но сами наши идеи бывают ошибочными - отсюда и ошибки в программах. 2.6 Наши методы оценивания, основанные на учете затрат, смешивают затраты с полученным результатом. Человеко-месяц является ошибочным и опасным заблуждением, поскольку предполагает, что месяцы и количество людей можно менять местами. 2.7 Разделение задачи между несколькими людьми вызывает дополнительные затраты на обучение и обмен информацией. 2.8 Мое практическое правило: 1/3 времени - на проектирование, 1/6 - на написание программы, 1/4 - на тестирование компонентов и 1/4 - на системное тестирование. 2.9 Как научной дисциплине нам не хватает методов оценки. 2.10 Поскольку мы не уверены в своих оценках сроков работы, нам часто не достает смелости упрямо отстаивать их под нажимом руководства и клиентов. 2.11 Закон Брукса: если проект не укладывается в сроки, то добавление рабочей силы задержит его еще больше. 2.12 Добавление рабочей силы увеличивает общий объем затрат тремя путями: труд по перекраиванию задач и происходящее при этом нарушение работы, обучение новых людей, дополнительное общение. Глава 3. Операционная бригада 3.1 Самые лучшие программисты-профессионалы в 10 раз продуктивнее слабых при равной подготовке и двухлетнем стаже (Сакман, Грант и Эриксон). 3.2 Данные Сакмана, Гранта и Эриксона не выявили корреляции между опытом и продуктивностью. Я думаю, что это всегда так. 3.3 Лучше всего иметь маленькую активную команду - как можно меньше мыслителей. 3.4 Часто лучше всего, если команда состоит из двух человек, один из которых является лидером. (Обратите внимание, как Богом задуман брак.) 3.5 Для создания действительно крупных систем маленькая активная команда работает слишком медленно. 3.6 Опыт разработки большинства действительно больших систем показывает, что подход к ускорению с позиций грубой силы оказывается дорогостоящим, медленным, неэффективным и приводит к появлению систем, не являющихся концептуально целостными. 3.7 Организация по типу хирургических бригад с главным программистом предлагает способ достижения целостности продукта благодаря его проектированию в нескольких головах и общей продуктивности благодаря наличию многочисленных помощников при радикально сокращенном обмене информацией. Глава 4. Аристократия, демократия и системное проектирование 4.1 "Концептуальная целостность является наиболее важным соображением при проектировании систем." 4.2 "Окончательную оценку проекту системы дает отношение функциональности к сложности концепций", а не только богатство функций. (Это соотношение является мерой простоты использования, пригодной как для простого, так и для сложного использования.) 4.3 Для достижения концептуальной целостности проект должен создаваться одним человеком или группой единомышленников. 4.4 "Отделение разработки архитектуры от реализации является эффективным способом достижения концептуальной целостности при работе над очень большими проектами." (И маленькими тоже.) 4.5 "Если вы хотите, чтобы система обладала концептуальной целостностью, кто- то один должен взять руководство концепциями. Это аристократизм, который не нуждается в извинениях." 4.6 Дисциплина полезна искусству. Получение архитектуры извне усиливает, а не подавляет творческую активность группы исполнителей. 4.7 Концептуально целостные системы быстрее разрабатываются и тестируются. 4.8 Проектирование архитектуры, разработку и реализацию можно в значительной мере осуществлять параллельно. (Проектирование аппаратного и программного обеспечения тоже могут проходить параллельно.) Глава 5. Эффект второй системы 5.1 Связь, установленная на ранних этапах и продолжающаяся непрерывно, может дать архитектору верную оценку стоимости, а разработчику - уверенность в проекте, не снимая при этом четкого разграничения сфер ответственности. 5.2 Как архитектору успешно влиять на реализацию: - Помнить, что ответственность за творчество, проявляемое при реализации, несет строитель, поэтому архитектор только предлагает. - Всегда быть готовым предложить некоторый способ реализации своих замыслов и быть готовым согласиться с любым другим способом, который не хуже. - Выдвигая такие предложения, действовать тихо и частным образом. - Не рассчитывать на признательность за предложенные усовершенствования. - Выслушивать предложения разработчиков по усовершенствованию архитектуры. 5.3 Из всех проектируемых систем наибольшую опасность представляет вторая по счету; обычно ее приходится перепроектировать заново. 5.4 OS/360 является ярким примером эффекта второй системы. (Похоже, что Windows NT - это пример для 1990 года.) 5.5 Достойной внимания практикой является предварительное назначение функциям величин в байтах и микросекундах. Глава 6. Донести слово 6.1 Даже в большой команде проектировщиков оформление результатов нужно поручить одному или двум людям, чтобы обеспечить согласованность мини- решений. 6.2 Важно явно определить те части архитектуры, которые не прописаны столь же тщательно, как остальные. 6.3 Необходимо иметь как формальное описание проекта - для точности, так и текстуальное - для понимания. 6.4 Либо формальное, либо текстуальное определения выбираются в качестве стандарта, при этом второе определение является производным. Каждое определение может выступать в любой из ролей. 6.5 Реализация, в том числе модель, может служить определением архитектуры; такое использование имеет существенные недостатки. 6.6 Прямое включение является очень искусным приемом для осуществления стандартов архитектуры в программном обеспечении (в аппаратном обеспечении - тоже: возьмите интерфейс Mac WIMP, встроенный в ROM). 6.7 Архитектурное "определение будет яснее, а (архитектурная) дисциплина крепче, если изначально строятся как минимум две реализации". 6.8 Важно, чтобы архитектор в телефонных разговорах отвечал исполнителям на их вопросы; обязательно нужно регистрировать эти разговоры в журнале и доводить их до общего сведения. (Сейчас для этого предпочтительнее электронная почта.) 6.9 "Лучший друг менеджера проекта - его постоянный противник, независимая организация, тестирующая продукт." Глава 7. Почему не удалось построить Вавилонскую башню? 7.1 Проект Вавилонской башни провалился из-за недостатка обмена информацией и, как следствие, организации. Обмен информацией 7.2 "Отставание графика, несоответствие функциональности, системные ошибки - все это из-за того, что левая рука не знает, что творит правая." Предположения команд расходятся. 7.3 Бригады должны поддерживать между собой связь всеми возможными способами: неформально, путем регулярных совещаний по проекту с техническими отчетами и через общую рабочую тетрадь проекта. (А также электронную почту.) Рабочая тетрадь проекта 7.4 Рабочая тетрадь проекта есть "не столько отдельный документ, сколько структура, налагаемая на все документы, которые, так или иначе, будут созданы во время выполнения проекта." 7.5 "Все документы проекта должны входить в эту структуру (рабочей тетради)." 7.6 Структуру рабочей тетради нужно проектировать тщательно и рано. 7.7 Правильное структурирование текущей документации с самого начала позволяет "составленные позднее документы оформить в виде отрывков, которые вписываются в эту структуру" и улучшает руководства по продукту. 7.8 "Каждый член команды должен видеть все материалы (рабочей тетради)." (Сейчас я бы сказал "должен иметь возможность видеть". Например, достаточно WWW-страниц.) 7.9 Своевременное обновление может иметь критическое значение. 7.10 Необходимо, чтобы внимание пользователя было особо привлечено к изменениям, произошедшим после его последнего прочтения, причем с пометками об их значении. 7.11 Рабочая тетрадь проекта OS/360 начиналась с бумажного варианта с последующим переходом на микрофиши. 7.12 Сегодня (и даже в 1975 году) общий электронный блокнот является значительно лучшим, более дешевым и простым механизмом достижения этих целей. 7.13 Необходимо помечать текст с помощью полосок изменения дат пересмотра (или их функционального эквивалента). Так же необходима сводка изменений по типу стека. 7.14 Парнас старается доказать, что стремление к тому, чтобы каждый видел все, совершенно ошибочно: части должны инкапсулироваться таким образом, чтобы никому не требовалось или не разрешалось видеть содержание каких- либо частей, кроме своих собственных, а видны могут быть только интерфейсы. 7.15 Предложение Парнаса - путь к катастрофе. (Парнас вполне убедил меня в обратном, и я совершенно изменил свое мнение.) Организация 7.16 Задачей организации является сокращение объема необходимого общения и согласования. 7.17 Организация заключает в себе разделение труда и специализацию функций с целью сократить обмен информацией. 7.18 Обычная древовидная организация отражает структурный принцип власти, который показывает, что нельзя одновременно служить двум хозяевам. 7.19 Структура обмена информацией в организации является не деревом, а сетью, и нужно придумать различные виды специальных организационных механизмов ("пунктирные линии"), чтобы преодолеть дефицит обмена информацией в древовидной организации. 7.20 В каждом субпроекте есть две руководящие должности: продюсер и технический директор, или архитектор. Их функции совершенно различны и требуют разных способностей. 7.21 Вполне эффективным может быть любой тип взаимоотношений между этими двумя должностями: - Это может быть одно лицо. - Продюсер может быть начальником, а директор - его правой рукой. - Директор может быть начальником, а продюсер - его правой рукой. Глава 8. Объявляя удар 8.1 Нельзя точно оценить общий объем или график работ программного проекта, просто оценив время написания программы и умножив на некоторые коэффициенты для остальных частей задания. 8.2 Данные, относящиеся к созданию небольших отдельных систем, не применимы к проектам создания программных комплексов. 8.3 Объем работ растет как степенная функция размера программы. 8.4 Некоторые опубликованные исследования показывают, что показатель степени примерно равен 1,5. (Результаты Бема с этим не согласуются и меняются от 1,05 до 1,2.)1 8.5 Данные Портмана по ICL показывают, что занятые на полный рабочий день программисты только около 50 процентов времени занимаются программированием и отладкой, а остальное время занимают разные дополнительные задачи. 8.6 По данным Арона из IBM, производительность труда лежит в пределах от 1,5 до 10 тысяч строк программы на человека в год в зависимости от количества взаимодействий между частями системы. 8.7 По данным Харра из Bell Labs, производительность труда при задаче типа разработки операционной системы составила около 0,6 тысяч строк кода на человека в год, а при разработке компиляторов - 2,2 тысячи для законченных продуктов. 8.8 Данные Брукса по OS/360 согласуются с данными Харра: 0,6-0,8 тысяч строк кода на человеко-год для операционных систем и 2-3 тысячи для компиляторов. 8.9 Данные Корбато по проекту МТИ MULTICS показывают, что производительность труда при разработке смеси операционной системы и компиляторов составила 1,2 тысяч строк кода на человека в год, но это строки кода PL/I, а остальные данные относятся к строкам кода ассемблера! 8.10 Производительность примерно постоянна в переводе на элементарные операторы. 8.11 При использовании подходящих языков высокого уровня производительность можно увеличить в пять раз. Глава 9. Два в одном 9.1 Если не считать времени выполнения, то главные издержки приходятся на занимаемое программой пространство памяти. Это в особенности верно для операционных систем, значительная часть которых остается резидентной. 9.2 Несмотря на это, деньги, потраченные на память для размещения программы, дают очень хорошее улучшение характеристик на единицу вложений - лучшее, чем все другие способы инвестирования в конфигурацию. Плох не размер программы, а лишний размер. 9.3 Разработчик программы должен устанавливать задание по размеру, контролировать размер и придумывать методы сокращения размера, так же, как разработчик аппаратной части делает это для деталей. 9.4 Ресурсы по памяти должны явно задавать не только размер резидентной части, но и интенсивность обращений программы к диску. 9.5 Ресурсы памяти должны привязываться к назначению функций: точно определяйте, что должен делать модуль, когда задаете его размеры. 9.6 Группы в составе больших бригад склонны производить оптимизацию в своих узких интересах, не думая о конечном эффекте, который она окажет на пользователя. Эта потеря ориентации является большой опасностью для крупных проектов. 9.7 На всем протяжении реализации системные архитекторы должны постоянно проявлять бдительность с целью непрерывного обеспечения целостности системы. 9.8 Воспитание общесистемного и ориентированного на пользователя подхода является, возможно, главной задачей менеджера по программированию. 9.9 Нужно уже на ранних этапах определить, насколько детализированным будет предоставляемый пользователю выбор опций, поскольку объединение опций в группы сберегает память (а часто и расходы на маркетинг). 9.10 Важно определить размер транзитной памяти, связанный с размером перегружаемого кода, поскольку зависимость производительности от этого размера сильнее, чем линейная. (Этот пункт полностью устарел благодаря наличию виртуальной памяти и дешевизне физической памяти. Теперь пользователи обычно покупают память в количестве, достаточном для размещения всего кода основных приложений.) 9.11 Для достижения хорошего компромисса между пространством и временем необходимо проводить обучение технике программирования, присущей данному языку или машине, особенно если они новые. 9.12 У программирования есть технология, и каждый проект нуждается в библиотеке стандартных компонентов. 9.13 Библиотеки программ должны иметь по две версии каждого компонента - быструю и компактную. (Похоже, что сегодня это устарело.) 9.14 Компактные и быстрые программы почти всегда являются результатом стратегического прорыва, а не тактической грамотности. 9.15 Таким прорывом часто является новый алгоритм. 9.16 Еще чаще прорыв происходит благодаря изменению представления данных или таблиц. Представление - сущность программирования. Глава 10. Документарная гипотеза 10.1 Гипотеза: Среди моря бумаг несколько документов становятся критически важными осями, вокруг которых вращается все управление проектом. Они являются главными личными инструментами менеджера. 10.2 Для проекта разработки компьютера решающими документами являются цели, руководство, график, бюджет, организационная структура, план помещений, а также оценка, прогноз и цены для самой машины. 10.3 Для факультета университета важнейшие документы аналогичны: цели, требования к соискателям степеней, описания курсов, предложения по научной работе, расписание занятий и план обучения, бюджет, план помещений, а также назначения преподавателей и аспирантов. 10.4 Для программного проекта требования те же: цели, руководство пользователя, внутренняя документация, график, бюджет, организационная структура и план помещений. 10.5 Поэтому даже для самого маленького проекта менеджер с самого начала должен формализовать такой набор документов. 10.6 Подготовка каждого документа их этого маленького набора концентрирует мысль и кристаллизует обсуждение. При изложении на бумаге требуется принятие сотен мини-решений, и их наличие отличает четкую и точную политику от расплывчатой. 10.7 Сопровождение каждого важного документа требует наличия механизма слежения за состоянием и предупреждения. 10.8 Каждый документ в отдельности служит контрольным списком и базой данных. 10.9 Важнейшая задача менеджера - обеспечить общее движение в одном направлении. 10.10 Главная постоянная задача менеджера - общение, а не принятие решений; документы информируют всю команду о планах и решениях. 10.11 Только маленькая часть, возможно, 20 процентов, рабочего времени администратора занята задачами, которые требуют сведений, отсутствующих в его памяти. 10.12 По этой причине модная идея "всеохватывающей информационной системы для управления", обеспечивающей поддержку руководителя, основывается на неверной модели поведения руководителя. Глава 11. Планируйте на выброс 11.1 Инженеры-химики выяснили, что осуществленный в лаборатории процесс нельзя одним махом перенести в заводские условия, но необходимо построить опытный завод, чтобы получить опыт наращивания количеств веществ и функционирования в незащищенных средах. 11.2 Этот промежуточный шаг в равной мере необходим для программных продуктов, но для инженеров-программистов пока не стало обычной практикой проводить полевые испытания опытной системы, прежде чем начинать поставки готового продукта. (Сейчас это уже стало общей практикой благодаря выпуску бета-версий. Это не то же самое, что макет с ограниченной функциональностью, альфа-версия, которую я также пропагандирую.) 11.3 Для большинства проектов первую построенную версию едва можно использовать: слишком медленная, слишком большая, слишком сложная в применении, или все это вместе. 11.4 Отбросить и перепроектировать можно все сразу, а можно по частям, но все равно это придется сделать. 11.5 Поставка первой системы (хлама) клиенту позволяет выиграть время, но происходит это ценой мучений пользователей, отвлечения разработчиков, поддерживающих систему во время перепроектирования и дурной репутации продукта, которую будет трудно победить. 11.6 Поэтому планируйте выбросить первую версию - вам все равно придется это сделать. 11.7 "Программист поставляет удовлетворение потребности пользователя, а не какой-то осязаемый продукт" (Косгроув). 11.8 Как фактические потребности пользователя, так и понимание им своих потребностей меняются во время создания, тестирования и использования программы. 11.9 Податливость и неосязаемость программного продукта побуждают его создателей (исключительно) к вечному изменению требований. 11.10 Некоторые законные изменения в задачах (и стратегиях разработки) неизбежны, и лучше подготовиться к ним заранее, чем предполагать, что их не будет. 11.11 Способы проектирования системы с учетом будущих изменений, особенно структурное программирование с тщательным документированием интерфейсов модулей, хорошо известны, но не всегда применяются. Полезно также, где только можно, использовать технологии табличного управления. (Такая техника благодаря стоимости и размеру памяти в настоящее время применяется все более успешно.) 11.12 Для сокращения вносимых при изменениях ошибок следует использовать языки высокого уровня, операции времени компиляции, встраивание ссылок на объявления и технику самодокументирования. 11.13 Вносите изменения квантами в хорошо определенные нумерованные версии. (Сейчас это обычная практика.) Планируйте организацию для изменени