Файл: Руководство по стилю программирования и конструированию по.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 30.11.2023

Просмотров: 775

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

СОДЕРЖАНИЕ

ГЛАВА 6 Классы129쐽Вариант 3: использовать неявные экземпляры (с большой осторожностью). Вы должны создать новый сервис — скажем, SetCurrentFont ( fontId ), — при вызо- ве которого заданный экземпляр шрифта делается текущим. После этого все остальные сервисы используют текущий шрифт, благодаря чему в них не нуж- но передавать параметр fontId. При разработке простых приложений такой под- ход может облегчить использование нескольких экземпляров данных. В слож- ных приложениях подобная зависимость от состояния в масштабе всей сис- темы подразумевает, что вы должны следить за текущим экземпляром шрифта во всем коде, вызывающем методы Font; разумеется, сложность программы при этом повышается. Каким бы ни был размер приложения, всегда можно найти более удачные альтернативы данному подходу.Внутри АТД вы можете реализовать работу с несколькими экземплярами данных как угодно, но вне его при использовании языка, не являющегося объектно-ори- ентированным, возможны только три указанных варианта.АТД и классыАбстрактные типы данных лежат в основе концепции классов. В языках, поддержи- вающих классы, каждый АТД можно реализовать как отдельный класс. Однако обыч- но с классами связывают еще две концепции: наследование и полиморфизм. Може- те рассматривать класс как АТД, поддерживающий наследование и полиморфизм.6.2. Качественные интерфейсы классовПервый и, наверное, самый важный этап разработки высококачественного клас- са — создание адекватного интерфейса. Это подразумевает, что интерфейс дол- жен представлять хорошую абстракцию, скрывающую детали реализации класса.Хорошая абстракцияКак я говорил в подразделе «Определите согласованные абстракции» раздела 5.3,под абстракцией понимается представление сложной операции в упрощенной форме. Интерфейс класса — это абстракция реализации класса, скрытой за ин- терфейсом. Интерфейс класса должен предоставлять группу методов, четко согла- сующихся друг с другом.Рассмотрим для примера класс «сотрудник». Он может содержать такие данные,как фамилия сотрудника, адрес, номер телефона и т. д., и предлагать методы ини- циализации и использования этих данных. Вот как мог бы выглядеть такой класс:Пример интерфейса, формирующего хорошую абстракцию (C++)class Employee {public: // открытые конструкторы и деструкторы Employee(); Employee( FullName name, String address, String workPhone,Перекрестная ссылка Примеры кода в этой книге отформати- рованы с использованием кон- венции, поддерживающей сход- ство стилей между нескольки- ми языками. Об этой конвенции(и разных стилях кодирования)см. подраздел «Программирова- ние с использованием несколь- ких языков» раздела 11.4. 130ЧАСТЬ II Высококачественный код String homePhone, TaxId taxIdNumber, JobClassification jobClass ); virtual Employee(); // открытые методы FullName GetName() const; String GetAddress() const; String GetWorkPhone() const; String GetHomePhone() const; TaxId GetTaxIdNumber() const; JobClassification GetJobClassification() const;private:};Внутри этот класс может иметь дополнительные методы и данные, поддержива- ющие работу этих сервисов, но пользователям класса знать о них не нужно. Пред- ставляемая интерфейсом этого класса абстракция великолепна, потому что все методы интерфейса служат единой согласованной цели.Интерфейс, представляющий плохую абстракцию, содержал бы набор разнород- ных методов, например:Пример интерфейса, формирующегоплохую абстракцию (C++)class Program {public: // открытые методы void InitializeCommandStack(); void PushCommand( Command command ); Command PopCommand(); void ShutdownCommandStack(); void InitializeReportFormatting(); void FormatReport( Report report ); void PrintReport( Report report ); void InitializeGlobalData(); void ShutdownGlobalData();private:};Похоже, этот класс содержит методы работы со стеком команд, форматирования отчетов, печати отчетов и инициализации глобальных данных. Трудно увидеть связь между стеком команд, обработкой отчетов и глобальными данными. Интерфейс такого класса не формирует согласованную абстракцию, и класс обладает плохой ГЛАВА 6 Классы131связностью. В данном случае методы следует реорганизовать в более четкие классы,интерфейсы которых будут представлять более удачные абстракции.Если бы эти методы были частью класса Program, для формирования согласован- ной абстракции их можно было бы изменить так:Пример интерфейса, формирующего более удачную абстракцию (C++)class Program {public: // открытые методы void InitializeUserInterface(); void ShutDownUserInterface(); void InitializeReports(); void ShutDownReports();private:};В ходе очистки интерфейса одни его методы были перемещены в более подходя- щие классы, а другие были преобразованы в закрытые методы, используемые методом InitializeUserInterface() и другими методами.Данный способ оценки абстракции класса основан на изучении открытых методов класса, т. е. его интерфейса. Однако из того, что класс в целом формирует хорошую абстракцию, вовсе не следует, что его отдельные методы также представляют удач- ные абстракции. Рекомендации по проектированию методов см. в разделе 7.2.Чтобы ваши классы имели высококачественные абстрактные интерфейсы, соблю- дайте при их проектировании следующие принципы.Выражайте в интерфейсе класса согласованный уровень абстракцииКлассы полезно рассматривать как механизмы реализации абстрактных типов дан- ных, описанных в разделе 6.1. В идеале каждый класс должен быть реализацией только одного АТД. Если класс реализует более одного АТД или если вам не уда- ется определить, реализацией какого АТД класс является, самое время реоргани- зовать класс в один или несколько хорошо определенных АТД.Так, следующий класс имеет несогласованный интерфейс, потому что формируе- мый им уровень абстракции непостоянен:Пример интерфейса, включающего разныеуровни абстракции (C++)class EmployeeCensus: public ListContainer {public: // открытые методы 132ЧАСТЬ II Высококачественный кодАбстракция, формируемая этими методами, относится к уровню «employee» (сотрудник). void AddEmployee( Employee employee ); void RemoveEmployee( Employee employee );Абстракция, формируемая этими методами, относится к уровню «list» (список). Employee NextItemInList(); Employee FirstItem(); Employee LastItem();private:};Этот класс представляет два АТД: Employee и ListContainer (список-контейнер).Подобные смешанные абстракции часто возникают, когда программист реализу- ет класс при помощи класса-контейнера или других библиотечных классов и не скрывает этот факт. Спросите себя, должна ли информация об использовании класса-контейнера быть частью абстракции. Обычно это является деталью реали- зации, которую следует скрыть от остальных частей программы, например так:Пример интерфейса, формирующего согласованную абстракцию (C++)class EmployeeCensus {public: // открытые методыАбстракция, формируемая всеми этими методами, теперь относится к уровню «employee». void AddEmployee( Employee employee ); void RemoveEmployee( Employee employee ); Employee NextEmployee(); Employee FirstEmployee(); Employee LastEmployee();private:Тот факт, что класс использует библиотеку ListContainer, теперь скрыт. ListContainer m_EmployeeList;};Программисты могут утверждать, что наследование от ListContainer удобно, потому что оно поддерживает полиморфизм, позволяя создать внешний метод поиска или сортировки, принимающий объект ListContainer. Но этот аргумент не проходит главный тест на уместность наследования: «Используется ли наследование толь- ко для моделирования отношения „является“?» Наследование класса EmployeeCensus(каталог личных дел сотрудников) от класса ListContainer означало бы, что Employee-Census «является» ListContainer, что, очевидно, неверно. Если абстракция объектаEmployeeCensus заключается в том, что он поддерживает поиск или сортировку,>>>> ГЛАВА 6 Классы133эти возможности должны быть явными согласованными частями интерфейса класса.Если представить открытые методы класса как люк, предотвращающий попадание воды в подводную лодку, несогласованные открытые методы — это щели. Вода не будет протекать через них так быстро, как через открытый люк, но позже лодка все же потонет. На практике при смешении уровней абстракции именно это и проис- ходит. По мере изменений программы смешанные уровни абстракции делают ее все менее и менее понятной, пока в итоге код не станет совсем загадочным.Убедитесь, что вы понимаете, реализацией какой абстракцииявляется класс Некоторые классы очень похожи, поэтому при разра- ботке класса нужно понимать, какую абстракцию должен представлять его интерфейс. Однажды я работал над программой, которая должна была под- держивать редактирование информации в табличном формате. Сначала мы хо- тели использовать простой элемент управления «grid» (сетка), но доступные эле- менты управления этого типа не позволяли закрашивать ячейки ввода данных в другой цвет, поэтому мы выбрали элемент управления «spreadsheet» (электронная таблица), который такую возможность поддерживал.Элемент управления «электронная таблица» был гораздо сложнее «сетки» и пре- доставлял около 150 методов в сравнении с 15 методами «сетки». Так как наша цель заключалась в использовании «сетки», а не «электронной таблицы», мы поручили одному программисту написать класс-оболочку, который скрывал бы тот факт, что мы подменили один элемент управления другим. Он поворчал по поводу ненуж- ных затрат и бюрократии, ушел и вернулся через пару дней с классом-оболочкой,который честно предоставлял все 150 методов «электронной таблицы».Но нам было нужно не это — нам требовался интерфейс «сетки», инкапсулирую- щий тот факт, что за кулисами мы использовали гораздо более сложную «элект- ронную таблицу». Программисту следовало предоставить доступ только к 15 ме- тодам «сетки» и еще одному, шестнадцатому методу, поддерживающему закраши- вание ячеек. Открыв доступ ко всем 150 методам, программист подверг нас риску того, что после нескольких изменений реализации класса нам в итоге придется поддерживать все 150 открытых методов. Он не смог обеспечить нужную нам инкапсуляцию и проделал гораздо больше работы, чем стоило.В зависимости от конкретных обстоятельств оптимальной абстракцией может оказаться как «сетка», так и «электронная таблица». Если приходится выбирать между двумя похожими абстракциями, убедитесь, что выбор правилен.Предоставляйте методы вместе с противоположными им методамиБольшинство операций имеет соответствующие противоположные операции. Если одна из операций включает свет, вам, вероятно, понадобится и операция, его вы- ключающая. Если одна операция добавляет элемент в список, элементы скорее всего нужно будет и удалять. Если одна операция активизирует элемент меню, вторая,наверное, должна будет его деактивизировать. При проектировании класса про- верьте каждый открытый метод на предмет того, требуется ли вам его противо- положность. Создавать противоположные методы, не имея на то причин, не сле- дует, но проверить их целесообразность нужно. 134ЧАСТЬ II Высококачественный кодУбирайте постороннюю информацию в другие классы Иногда вы будете обнаруживать, что одни методы класса работают с одной половиной данных, а другие — с другой. Это значит, что вы имеете дело с двумя классами, скрывающи- мися под маской одного. Разделите их!По мере возможности делайте интерфейсы программными, а не семан-тическими Каждый интерфейс состоит из программной и семантической ча- стей. Первая включает типы данных и другие атрибуты интерфейса, которые могут быть проверены компилятором. Вторая складывается из предположений об ис- пользовании интерфейса, которые компилятор проверить не может. Семантический интерфейс может включать такие соображения, как «Метод А должен быть выз- ван перед Методом B» или «Метод А вызовет ошибку, если переданный в него Эле- мент Данных 1 не будет перед этим инициализирован». Семантический интерфейс следует документировать в комментариях, но вообще интерфейсы должны как можно меньше зависеть от документации. Любой аспект интерфейса, который не может быть проверен компилятором, является потенциальным источником оши- бок. Старайтесь преобразовывать семантические элементы интерфейса в программ- ные, используя утверждения (assertions) или иными способами.Опасайтесь нарушения целостности интерфейса приизменении класса При модификации и расширении клас- са часто обнаруживается дополнительная нужная функци- ональность, которая не совсем хорошо соответствует интер- фейсу первоначального класса, но плохо поддается реализации иным образом. Так,класс Employee может превратиться во что-нибудь вроде:Пример интерфейса, изуродованного при сопровождениипрограммы (C++)class Employee {public: // открытые методы FullName GetName() const; Address GetAddress() const; PhoneNumber GetWorkPhone() const; bool IsJobClassificationValid( JobClassification jobClass ); bool IsZipCodeValid( Address address ); bool IsPhoneNumberValid( PhoneNumber phoneNumber ); SqlQuery GetQueryToCreateNewEmployee() const; SqlQuery GetQueryToModifyEmployee() const; SqlQuery GetQueryToRetrieveEmployee() const;private:};То, что начиналось как ясная абстракция, превратилось в смесь почти несогласо- ванных методов. Между сотрудниками и методами, проверяющими корректностьПерекрестная ссылка О поддер- жании качества кода при его изменении см. главу 24. ГЛАВА 6 Классы135почтового индекса, номера телефона или ставки зарплаты (job classification), нет логической связи. Методы, предоставляющие доступ к деталям SQL-запросов, от- носятся к гораздо более низкому уровню абстракции, чем класс Employee, нару- шая общую абстракцию класса.Не включайте в класс открытые члены, плохо согласующиеся с абстрак-цией интерфейса Добавляя новый метод в интерфейс класса, всегда спраши- вайте себя: «Согласуется ли этот метод с абстракцией, формируемой существую- щим интерфейсом?» Если нет, найдите другой способ внесения изменения, позво- ляющий сохранить согласованность абстракции.Рассматривайте абстракцию и связность вместе Понятия абстракции и связности (cohesion) тесно связаны: интерфейс класса, представляющий хорошую абстракцию, обычно отличается высокой связностью. И наоборот: классы, имею- щие высокую связность, обычно представляют хорошие абстракции, хотя эта связь выражена слабее.Я обнаружил, что при повышенном внимании к абстракции, формируемой ин- терфейсом класса, проект класса получается более удачным, чем при концентра- ции на связности класса. Если вы видите, что класс имеет низкую связность и не знаете, как это исправить, спросите себя, представляет ли он согласованную аб- стракцию.Хорошая инкапсуляцияКак я уже говорил в разделе 5.3, инкапсуляция является бо- лее строгой концепцией, чем абстракция. Абстракция по- могает управлять сложностью, предоставляя модели, позво- ляющие игнорировать детали реализации. Инкапсуляция не позволяет узнать детали реализации, даже если вы этого захотите.Две этих концепции связаны: без инкапсуляции абстракция обычно разрушается.По своему опыту могу сказать, что вы или имеете и абстракцию, и инкапсуляцию,или не имеете ни того, ни другого. Промежуточных вариантов нет.Минимизируйте доступность классов и их членов Ми- нимизация доступности — одно из нескольких правил, под- держивающих инкапсуляцию. Если вы не можете понять,каким делать конкретный метод: открытым, закрытым или защищенным, — некоторые авторы советуют выбирать са- мый строгий уровень защиты, который работает (Meyers,1998; Bloch, 2001). По-моему, это прекрасное правило, но мне кажется, что еще важнее спросить себя: «Какой вари- ант лучше всего сохраняет целостность абстракции интер- фейса?» Если предоставление доступа к методу согласуется с абстракцией, сделайте его открытым. Если вы не уверены, скрыть больше обычно предпочтительнее, чем скрыть меньше.Не делайте данные-члены открытыми Предоставление доступа к данным- членам нарушает инкапсуляцию и ограничивает контроль над абстракцией. КакПерекрестная ссылка Об инкап- суляции см. подраздел «Инкап- сулируйте детали реализации»раздела 5.3.Самым важным отличием хоро- шо спроектированного модуля от плохо спроектированного яв- ляется степень, в которой мо- дуль скрывает свои внутренние данные и другие детали реали- зации от других модулей.Джошуа Блох (Joshua Bloch) 136ЧАСТЬ II Высококачественный код указывает Артур Риэль, класс Point (точка), который предоставляет доступ к дан- ным:float x;float y;float z;нарушает инкапсуляцию, потому что клиентский код может свободно делать с данными Point что угодно, при этом сам класс может даже не узнать об их изме- нении (Riel, 1996). В то же время класс Point, включающий члены:float GetX();float GetY();float GetZ();void SetX( float x );void SetY( float y );void SetZ( float z );поддерживает прекрасную инкапсуляцию. Вы не имеете понятия о том, реализо- ваны ли данные как float x, y и z, хранит ли класс Point эти элементы как double,преобразуя их в float, или же он хранит их на Луне и получает через спутник.Не включайте в интерфейс класса закрытые детали реализации Истинная инкапсуляция не позволяла бы узнать детали реализации вообще. Они были бы скрыты и в прямом, и в переносном смыслах. Однако популярные языки — в том числе C++ — требуют, чтобы программисты раскрывали детали реализации в интерфейсе класса, например:Пример обнародования деталей реализации класса (C++)class Employee {public: Employee( FullName name, String address, String workPhone, String homePhone, TaxId taxIdNumber, JobClassification jobClass ); FullName GetName() const; String GetAddress() const;private:Обнародованные детали реализации. String m_Name; String m_Address; int m_jobClass;};> 1   ...   14   15   16   17   18   19   20   21   ...   104

ГЛАВА 20 Качество ПО463Табл. 20-2. Эффективность нахождения дефектовпри использовании разных методикМетодикаМинимальнаяТипичнаяМаксимальнаяустранения дефектовэффективностьэффективностьэффективностьНеформальные25%35%40%обзоры проектаФормальные45%55%65%инспекции проектаНеформальные20%25%35%обзоры кодаФормальные45%60%70%инспекции кодаМоделирование35%65%80%или прототипированиеСамостоятельная20%40%60%проверка кодаБлочное тестирование15%30%50%Тестирование новых20%30%35%функций (компонентов)Интеграционное25%35%40%тестированиеРегрессивное15%25%30%тестированиеТестирование системы25%40%55%Ограниченное бета-тес- 25%35%40%тирование (менее чем в 10 организациях)Крупномасштабное бета- 60%75%85%тестирование (более чем в 1000 организаций)Источники: «Programming Productivity» (Jones, 1986a), «Software Defect-RemovalEfficiency» (Jones, 1996) и «What We Have Learned About Fighting Defects» (Shull et al., 2002).Самое интересное в этих данных то, что типичная эффективность об- наружения дефектов при использовании любой методики не превышает75% и что в среднем она равна примерно 40%. Более того, самые попу- лярные методики — блочное тестирование и интеграционное тестирование — по- зволяют найти обычно только около 30–35% дефектов. Как правило, использует- ся подход, основанный на интенсивном тестировании, что позволяет устранить лишь около 85% дефектов. Ведущие организации используют более широкий ди- апазон методик, достигая при этом 95%-ой или более высокой эффективности ус- транения дефектов (Jones, 2000).Итак, если разработчики хотят достигнуть более высокой эффективности обна- ружения дефектов, они должны полагаться на комбинацию методик. Одно из подтверждений этого вывода было получено в классическом исследовании Глен- форда Майерса (Myers, 1978b). Участниками исследования были программисты,обладавшие минимум 7-, а в среднем — 11-летним опытом. Исследуемая программа 464ЧАСТЬ V Усовершенствование кода содержала 15 известных ошибок. Майерс попросил каждого программиста най- ти эти ошибки, используя одну из следующих методик:쐽тестирование выполнения программы по спецификации;쐽тестирование выполнения программы по спецификации с возможностью изу- чения исходного кода;쐽анализ/инспекция с использованием и спецификации, и исходного кода.Различия эффективности обнаружения дефектов оказались очень боль- шими: программисты нашли от 1 до 9 дефектов. Средний показатель был равен 5,1, или 1/3 от общего числа известных дефектов.При использовании одной методики никакая из них не имела статистически зна- чимого преимущества над любой другой. В то же время любая комбинация двух методик — в том числе использование одной методики двумя независимыми груп- пами — приводила к увеличению общего числа найденных дефектов почти вдвое.В исследованиях, проведенных в Лаборатории проектирования ПО NASA, компа- нии Boeing и других компаниях, было обнаружено, что разные программисты находят разные дефекты. Только примерно каждую пятую ошибку, обнаруженную в ходе инспекций, находят двое или более разработчиков (Kouchakdjian, Green,and Basili, 1989; Tripp, Struck, and Pflug, 1991; Schneider, Martin, and Tsai, 1992).Майерс обращает внимание на то, что поиск одних видов ошибок оказывается более эффективным при непосредственном участии людей (например, при инспекции или анализе кода), а других видов — при компьютерном тестировании (Myers, 1979).Этот вывод подтвердился в более позднем исследовании, показавшем, что чтение кода способствует нахождению дефектов интерфейса, а функциональное тести- рование — нахождению дефектов управляющих структур (Basili, Selby, and Hutchens,1986). Гуру тестирования Борис Бейзер (Boris Beizer) сообщает, что неформаль- ные подходы к тестированию обычно позволяют достигнуть покрытия кода тес- тами лишь на 50–60%, если только вы не используете анализатор покрытия(Johnson, 1994).Таким образом, методики поиска дефектов лучше применять в комбина- ции. Джонс (Jones) также подтверждает этот вывод. Используя исключи- тельно тестирование, высоких результатов добиться невозможно. Джонс сообщает, что комбинация блочного тестирования, функционального тестирования и тестирования системы часто приводит к обнаружению менее 60% дефектов, что обычно неприемлемо для конечного продукта.Эти данные также помогают понять, почему программисты, начинающие приме- нять дисциплинированную методику устранения дефектов, такую как экстремаль- ное программирование, добиваются более высокой степени устранения дефектов.Как показывает табл. 20-3, набор методик устранения дефектов, применяемых в экстремальном программировании, позволяет устранить около 90% дефектов в обычной ситуации и 97% в лучшем случае, что гораздо выше среднего для отрас- ли показателя, равного 85%. Некоторые программисты связывают этот факт с синергичными отношениями между методиками экстремального программиро- вания, но на самом деле это просто предсказуемый результат использования кон- кретного набора методик устранения дефектов. Эффективность других комбинаций методик может оказаться такой же или даже более высокой, поэтому выбор кон- ГЛАВА 20 Качество ПО465кретных методик устранения дефектов, позволяющих достичь желаемого уровня качества, является одним из аспектов эффективного планирования проекта.Табл. 20-3. Эффективность обнаружения дефектов, характернаядля экстремального программированияМетодика устраненияМинимальнаяТипичнаяМаксимальнаядефектовэффективностьэффективностьэффективностьНеформальные обзоры25%35%40%проекта (парное программи- рование)Неформальные обзоры кода20%25%35%(парное программирование)Самостоятельная20%40%60%проверка кодаБлочное тестирование15%30%50%Интеграционное25%35%40%тестированиеРегрессивное тестирование15%25%30%Общая эффективность74%90%97%устранения дефектовСтоимость нахождения дефектовНекоторые методики обнаружения дефектов дороже других. Наиболее экономич- ные при прочих равных условиях имеют наименьшую стоимость в расчете на один обнаруженный дефект. Равенством прочих условий пренебрегать нельзя, поскольку стоимость методики в расчете на один дефект зависит от общего числа обнару- женных дефектов, этапа обнаружения каждого дефекта и других факторов, не связанных с экономическими аспектами конкретной методики.Как правило, эксперименты показывают, что инспекции обходятся дешев- ле, чем тестирование. В исследовании, проведенном в Лаборатории про- ектирования ПО, было обнаружено, что при чтении кода число дефек- тов, находимых в час, было примерно на 80% более высоким, чем при тестирова- нии (Basili and Selby, 1987). В другой организации поиск дефектов проектирова- ния с использованием блочного тестирования был вшестеро дороже, чем при ис- пользовании инспекций (Ackerman, Buchwald, and Lewski, 1989). Более позднее ис- следование, проведенное в IBM, показало, что на обнаружение каждой ошибки раз- работчики тратили 3,5 человеко-часа в случае инспекций кода и 15–25 в случае тестирования (Kaplan, 1995).Стоимость исправления дефектовСтоимость нахождения дефектов — только одна часть уравнения. Другой частью является стоимость их исправления. На первый взгляд, методика обнаружения дефектов не играет роли: стоимость их исправления всегда будет одинаковой.Это неверно, потому что чем дольше дефект остается в системе, тем больше средств придется потратить на его устранение. Следовательно, методика, способствующая раннему обнаружению ошибок, снижает стоимость их исправления. Еще важнее 466ЧАСТЬ V Усовершенствование кода то, что одни методики — такие как инспекции — позволя- ют определить и симптомы, и причины дефектов за один этап; другие — например, тестирование — указывают на симптомы дефекта, но требуют выполнения дополнитель- ной работы для диагностики и устранения его причины. Витоге одноэтапные методики оказываются гораздо более дешевыми, чем двухэтапные.В одном из подразделений Microsoft обнаружили, что при использова- нии инспекции кода — одноэтапной методики — на нахождение и ис- правление дефекта уходит 3 часа, тогда как при использовании тестиро- вания — двухэтапной методики — на это требуется 12 часов (Moore, 1992). Кол- лофелло и Вудфилд сообщили, что при разработке программы из 700 000 строк,над которой работало более 400 программистов, обзоры кода имели гораздо бо- лее высокую экономическую эффективность, чем тестирование: прибыль на ин- вестированный капитал была равной 1,38 и 0,17 соответственно (Collofello andWoodfield, 1989).Суть сказанного в том, что эффективная программа контроля качества должна включать комбинацию методик, применяемых на всех стадиях разработки. Для достижения высокого качества ПО можно использовать следующую комбинацию:쐽формальные инспекции всех требований, всех аспектов архитектуры и всех проектов критических частей системы;쐽моделирование или прототипирование;쐽чтение или инспекции кода;쐽тестирование выполнения программы.20.4. Когда выполнять контроль качества ПО?Как было отмечено в главе 3, чем раньше ошибка внедряет- ся в приложение, тем сильнее она переплетается с другими частями приложения и тем больше средств придется потра- тить на ее устранение. Дефект в требованиях может вылить- ся в один или несколько дефектов в проекте, которые могут привести к появлению множества дефектов в коде. Ошибка в требованиях может привести к разработке дополнительных компонентов архитектуры или подтолкнуть к неудачным ар- хитектурным решениям. Дополнительные архитектурные компоненты требуют написания дополнительного кода, те- стов и документации. С другой стороны, ошибка в требованиях может привести к выбрасыванию частей архитектуры, кода и тестов. Если идея устранения ошибок из чертежей дома перед заливкой фундамента бетоном кажется вам разумной, то вы согласитесь и с тем, что дефекты требований и архитектуры также следует уст- ранять до того, как они повлияют на более поздние этапы разработки.Кроме того, ошибки в требованиях или архитектуре обычно имеют более широ- кие следствия, чем ошибки конструирования. Одна ошибка в архитектуре может затронуть несколько классов и десятки методов, тогда как одна ошибка констру-Перекрестная ссылка О зависи- мости стоимости исправления дефектов от срока их присут- ствия в системе см. раздел «Об- ращение к данным» раздела 3.1.Сами ошибки более подробно обсуждаются в разделе 22.4.Перекрестная ссылка Контроль качества предварительных дей- ствий — например, определения требований и разработки архи- тектуры — в этой книге не рас- сматривается. Информацию по этим темам можно найти в кни- гах, указанных в разделе «До- полнительные ресурсы» в кон- це этой главы. ГЛАВА 20 Качество ПО467ирования скорее всего повлияет только на один метод или класс. Это еще одно убедительное обоснование как можно более раннего нахождения ошибок.Дефекты проникают в ПО на всех стадиях разработки, поэтому контро- лю качества следует уделять должное внимание на всех этапах проекта,начиная с самых ранних. Контроль качества нужно внести в планы в начале работы над программой; его следует выполнять по мере прогресса; нако- нец, он должен подчеркивать удачное завершение работы над проектом.20.5. Главный Закон Контроля Качества ПОНи в одном ресторане посетителей не кормят бесплатно, и даже если б кормили, никто не смог бы поручиться за качество блюд. Однако разра- ботка ПО — совсем не кулинарное искусство, и качество ПО имеет одну важную необычную особенность. Главный Закон Контроля Качества ПО заключа- ется в том, что повышение качества системы снижает расходы на ее разработку.В основе этого закона лежит одно важное наблюдение: лучшим способом повы- шения производительности труда программистов и качества ПО является мини- мизация времени, затрачиваемого на исправление кода, чем бы оно ни объясня- лось: изменениями требований, изменениями проекта или отладкой. Средняя для отрасли производительность труда программистов эквивалентна примерно 10–50 строкам кода на одного человека в день (с учетом всех затрат, не связанных с кодированием). Написание 10–50 строк кода требует нескольких минут, — на что же уходит остальное время?Такая, казалось бы, низкая производительность труда час- тично объясняется тем, что в подобных средних показате- лях учитывается время, не связанное непосредственно с программированием. Время тестировщиков, руководителей,секретарей — все эти факторы включены в данный показа- тель. Определение требований, разработка архитектуры и другие действия, не относящиеся к кодированию, также отра- жены в «строках кода в день». Однако основные временные затраты объясняются не этим.Самый длительный этап в большинстве проектов — отладка и исправление не- правильного кода. При традиционном цикле разработки ПО эти действия зани- мают около 50% времени (см. раздел 3.1). Сокращение потребности в отладке,достигаемое благодаря предотвращению ошибок, повышает производительность труда. Следовательно, наиболее очевидный метод сокращения графика разработ- ки — повышение качества ПО и снижение объема времени, уходящего на его отладку и исправление.Этот анализ подтверждается реальными данными. В обзоре 50 проектов,потребовавших более 400 человеколет и включивших почти 3 000 000строк кода, проведенном в Лаборатории проектирования ПО NASA, было обнаружено, что повышенное внимание к контролю качества позволяло снизить уровень ошибок, но не повышало общие расходы на разработку (Card, 1987).Перекрестная ссылка О разли- чиях между написанием отдель- ной программы и созданием программного продукта см. под- раздел «Программы, продукты,системы и системные продукты»раздела 27.5. 468ЧАСТЬ V Усовершенствование кодаВ исследовании, проведенном в IBM, были получены аналогичные результаты:Программным проектам с наименьшими уровнями дефектов соответствовали самые короткие графики разработки и максимальные показатели производитель- ности труда… устранение дефектов на самом деле — самый дорогой и длитель- ный этап разработки ПО (Jones, 2000).Это верно и для противоположного края шкалы. В одном исследовании1985 года ученые попросили 166 профессиональных программистов написать программы по одной и той же спецификации. Итоговые про- граммы содержали в среднем 220 строк, а на их написание ушло в среднем чуть меньше 5 часов. Результаты оказались поистине удивительными: программисты,работавшие над своими программами средний объем времени, допустили наиболь- шее число ошибок. Программисты, которым потребовалось больше или меньше времени, допустили значительно меньше ошибок (DeMarco and Lister, 1985). Ре- зультаты показаны на рисунке 20-2.Рис. 20-2. Ни при самом быстром, ни при самом медленном подходе к разработкеПО не наблюдается наибольший уровень дефектовВ сравнении с самой быстрой группой двум самым медленным группам понадо- билось примерно в 5 раз больше времени для достижения результата с примерно тем же уровнем дефектов. Таким образом, на создание ПО без дефектов не всегда уходит больше времени, чем на написание ПО с дефектами.Вероятно, в некоторых случаях контроль качества требует значительных затрат.Если вы пишете приложение управления космическим кораблем или медицин- ской системой жизнеобеспечения, высокие требования к надежности ПО делают проект более дорогим.В сравнении с традиционным циклом «кодирование — тестирование — отладка»улучшенная программа контроля качества ПО оказывается более экономичной.Она перенаправляет ресурсы от отладки и рефакторинга к предварительным этапам контроля качества. Предварительные этапы влияют на качество системы больше,чем последующие, поэтому время, потраченное на предварительных этапах, по- зволяет сэкономить больше времени потом. Результатом является снижение уровня ГЛАВА 20 Качество ПО469дефектов, сокращение сроков разработки и снижение затрат. В трех следующих главах вы найдете еще несколько примеров, иллюстрирующих Главный ЗаконКонтроля Качества ПО.Контрольный список: план контроля качества Идентифицировали ли вы специфические характеристики качества, имеющие особую важность в вашем проекте? Сообщили ли вы другим программистам целевые характеристики качества? Провели ли вы различие между внешними и внутренними характеристика- ми качества? Обдумали ли вы, как некоторые характеристики могут усиливать или ос- лаблять другие? Призывает ли ваш проект к использованию нескольких методик обнаруже- ния ошибок, ориентированных на поиск разных видов ошибок? Составили ли вы план контроля качества, охватывающий все этапы разра- ботки ПО? Оцениваете ли вы качество системы каким-нибудь образом, чтобы можно было определить, повышается оно или понижается? Понимают ли руководители, что контроль качества требует дополнительных расходов в начале проекта, но зато позволяет добиться общей экономии средств?Дополнительные ресурсыСоставить список книг для этой главы несложно, потому что методики повышения качества ПО и производительности труда описываются почти во всех трудах, посвященных эф- фективным методологиям разработки ПО. Сложность в том, чтобы выделить книги,касающиеся непосредственно качества ПО. Ниже я указал две такие работы.Ginac, Frank P. Customer Oriented Software Quality Assurance. Englewood Cliffs, NJ: PrenticeHall, 1998. В этой очень краткой книге описаны атрибуты качества, метрики каче- ства, программы контроля качества, роль тестирования в контроле качества, а так- же известные программы повышения качества, в том числе модель CMM, разрабо- танная в институте Software Engineering Institute, и стандарты ISO серии 9000.Lewis, William E. Software Testing and Continuous Quality Improvement, 2d ed. Auer- bach Publishing, 2000. В этой книге можно найти подробное обсуждение цикла контроля качества, а также методик тестирования. Кроме того, в ней вы найдете много контрольных форм и списков.Соответствующие стандартыIEEE Std 730-2002 — стандарт IEEE планирования контроля качества ПО.IEEE Std 1061-1998 — стандарт IEEE методологии метрик качества ПО.IEEE Std 1028-1997 — стандарт обзоров ПО.http://cc2e.com/2043http://cc2e.com/2050http://cc2e.com/2057 470ЧАСТЬ V Усовершенствование кодаIEEE Std 1008-1987 (R1993) — стандарт блочного тестирования ПО.IEEE Std 829-1998 — стандарт документирования тестов ПО.Ключевые моменты쐽Высокого качества можно достичь без дополнительных затрат, но для этого вы должны перераспределить ресурсы и предотвращать дефекты вместо того,чтобы их исправлять.쐽Стремление к одним характеристикам качества препятствует достижению дру- гих. Четко определите цели, имеющие для вас первостепенную важность, и сообщите об этом всем членам группы.쐽Никакая методика обнаружения дефектов не является достаточно эффектив- ной. Тестирование само по себе — не самый лучший способ устранения оши- бок. Составляя программу контроля качества, предусмотрите применение не- скольких методик, позволяющих обнаружить разные виды ошибок.쐽Существуют многие эффективные методики контроля качества, применяемые как во время конструирования, так и до его начала. Чем раньше вы обнаружи- те дефект, тем слабее он переплетется с остальным кодом и тем меньше вреда он успеет принести.쐽В мире программирования контроль качества ориентирован на процесс.В отличие от промышленного производства разработка ПО не включает по- вторяющегося этапа, влияющего на конечный продукт, поэтому качество ре- зультата определяется процессом, используемым для разработки ПО. 1   ...   53   54   55   56   57   58   59   60   ...   104

ГЛАВА 32 Самодокументирующийся код775граммой, и после тщательного изучения документации он обнаружил только та- кой комментарий:MOV AX, 723h ; R. I. P. L. V. B.Поломав над ним голову всю ночь, программист в итоге все исправил и пошел домой спать. Несколько месяцев спустя он встретился с автором программы на конференции и узнал, что комментарий означал «Rest in peace, Ludwig van Beet- hoven» (Покойся в мире, Людвиг ван Бетховен). Бетховен умер в 1827 году, кото- рому соответствует шестнадцатеричное значение 723. Необходимость использо- вания значения 723h не имела никакого отношения к комментарию. &%@*?#%

БиблиографияNewcomer, Joseph M. 2000. «Optimization: Your Worst Enemy,» May 2000, www.flounder. com/optimization.htm.Norcio, A. F. 1982. «Indentation, Documentation and Programmer Comprehension.» Proceedings:Human Factors in Computer Systems, March 15–17, 1982, Gaithersburg, MD: 118–20.Norman, Donald A. 1988. The Psychology of Everyday Things. New York, NY: Basic Books. (Also published in paperback as The Design of Everyday Things. New York, NY: Doubleday, 1990.)Oman, Paul and Shari Lawrence Pfleeger, eds. 1996. Applying Software Metrics. Los Alamitos, CA:IEEE Computer Society Press.Oman, Paul W., and Curtis R. Cook. 1990a. «The Book Paradigm for Improved Maintenance.» IEEESoftware, January, 39–45.Oman, Paul W., and Curtis R. Cook. 1990b. «Typographic Style Is More Than Cosmetic.» Commu-nications of the ACM 33, no. 5 (May): 506–20.Ostrand, Thomas J., and Elaine J. Weyuker. 1984. «Collecting and Categorizing Software Error Data in an Industrial Environment.» Journal of Systems and Software 4, no. 4 (November): 289–300.Page-Jones, Meilir. 2000. Fundamentals of Object-Oriented Design in UML. Boston, MA: Addison-Wesley.Page-Jones, Meilir. 1988. The Practical Guide to Structured Systems Design. Englewood Cliffs, NJ:Yourdon Press.Parikh, G., and N. Zvegintzov, eds. 1983. Tutorial on Software Maintenance. Los Alamitos, CA: IEEEComputer Society Press.Parikh, Girish. 1986. Handbook of Software Maintenance. New York, NY: John Wiley & Sons.Parnas, David L. 1972. «On the Criteria to Be Used in Decomposing Systems into Modules.»Communications of the ACM 5, no. 12 (December): 1053–58.Parnas, David L. 1976. «On the Design and Development of Program Families.» IEEE Transactionson Software Engineering SE-2, 1 (March): 1–9.Parnas, David L. 1979. «Designing Software for Ease of Extension and Contraction.» IEEE Trans-actions on Software Engineering SE-5, no. 2 (March): 128–38.Parnas, David L. 1999. ACM Fellow Profile: David Lorge Parnas,» ACM Software Engineering Notes,May 1999, 10–14.Parnas, David L., and Paul C. Clements. 1986. «A Rational Design Process: How and Why to FakeIt.» IEEE Transactions on Software Engineering SE-12, no. 2 (February): 251–57.Parnas, David L., Paul C. Clements, and D. M. Weiss. 1985. «The Modular Structure of ComplexSystems.» IEEE Transactions on Software Engineering SE-11, no. 3 (March): 259–66.Perrott, Pamela. 2004. Private communication.Peters, L. J., and L. L. Tripp. 1976. «Is Software Design Wicked» Datamation, Vol. 22, No. 5 (May1976), 127–136.Peters, Lawrence J. 1981. Handbook of Software Design: Methods and Techniques. New York, NY:Yourdon Press.Peters, Lawrence J., and Leonard L. Tripp. 1977. «Comparing Software Design Methodologies.»Datamation, November, 89– 94.Peters, Tom. 1987. Thriving on Chaos: Handbook for a Management Revolution. New York, NY:Knopf.Petroski, Henry. 1994. Design Paradigms: Case Histories of Error and Judgment in Engineering.Cambridge, U.K.: Cambridge University Press.Pietrasanta, Alfred M. 1990. «Alfred M. Pietrasanta on Improving the Software Process.» SoftwareEngineering: Tools, Techniques, Practices 1, no. 1 (May/ June): 29–34. Библиография857Pietrasanta, Alfred M. 1991a. «A Strategy for Software Process Improvement.» Ninth Annual PacificNorthwest Software Quality Conference, October 7–8, 1991. Oregon Convention Center, Portland, ORPietrasanta, Alfred M. 1991b. «Implementing Software Engineering in IBM.» Keynote address. NinthAnnual Pacific Northwest Software Quality Conference, October 7– 8, 1991. Oregon ConventionCenter, Portland, OR.Pigoski, Thomas M. 1997. Practical Software Maintenance. New York, NY: John Wiley & Sons.Pirsig, Robert M. 1974. Zen and the Art of Motorcycle Maintenance: An Inquiry into Values. WilliamMorrow.Plauger, P. J. 1988. «A Designer’s Bibliography.» Computer Language, July, 17–22.Plauger, P. J. 1993. Programming on Purpose: Essays on Software Design. New York, NY: PrenticeHall.Plum, Thomas. 1984. C Programming Guidelines. Cardiff, NJ: Plum Hall.Polya, G. 1957. How to Solve It: A New Aspect of Mathematical Method, 2d ed. Princeton, NJ: PrincetonUniversity Press.Post, Ed. 1983. «Real Programmers Don’t Use Pascal,» Datamation, July 1983, 263– 265.Prechelt, Lutz. 2000. «An Empirical Comparison of Seven Programming Languages,» IEEE Computer,October 2000, 23–29.Pressman, Roger S. 1987. Software Engineering: A Practitioner’s Approach. New York, NY: McGraw-Hill.Pressman, Roger S. 1988. Making Software Engineering Happen: A Guide for Instituting theTechnology. Englewood Cliffs, NJ: Prentice Hall.Putnam, Lawrence H. 2000. «Familiar Metric Management – Effort, Development Time, and DefectsInteract.» Downloadable from www.qsm.com.Putnam, Lawrence H., and Ware Myers. 1992. Measures for Excellence: Reliable Software On Time,Within Budget. Englewood Cliffs, NJ: Yourdon Press, 1992.Putnam, Lawrence H., and Ware Myers. 1997. Industrial Strength Software: Effective ManagementUsing Measurement. Washington, DC: IEEE Computer Society Press.Putnam, Lawrence H., and Ware Myers. 2000. «What We Have Learned.» Downloadable fromwww.qsm.com, June 2000.Raghavan, Sridhar A., and Donald R. Chand. 1989. «Diffusing Software-Engineering Methods.»IEEE Software, July, 81–90.Ramsey, H. Rudy, Michael E. Atwood, and James R. Van Doren. 1983. «Flowcharts Versus ProgramDesign Languages: An Experimental Comparison.» Communications of the ACM 26, no. 6 (June):445–49.Ratliff, Wayne. 1987. Interview in Solution System.Raymond, E. S. 2000. «The Cathedral and the Bazaar,» www.catb.org/esr/writings/cathedral-bazaar.Raymond, Eric S. 2004. The Art of Unix Programming. Boston, MA: Addison-Wesley.Rees, Michael J. 1982. «Automatic Assessment Aids for Pascal Programs.» ACM Sigplan Notices 17,no. 10 (October): 33–42.Reifer, Donald. 2002. «How to Get the Most Out of Extreme Programming/Agile Methods,»Proceedings, XP/Agile Universe 2002. New York, NY: Springer; 185–196.Reingold, Edward M., and Wilfred J. Hansen. 1983. Data Structures. Boston, MA: Little, Brown.Rettig, Marc. 1991. «Testing Made Palatable.» Communications of the ACM 34, no. 5 (May): 25–29.Riel, Arthur J. 1996. Object-Oriented Design Heuristics. Reading, MA: Addison-Wesley.Rittel, Horst, and Melvin Webber. 1973. «Dilemmas in a General Theory of Planning.» Policy Sciences4: 155–69. 858БиблиографияRobertson, Suzanne, and James Robertson, 1999. Mastering the Requirements Process. Reading,MA: Addison-Wesley.Rogers, Everett M. 1995. Diffusion of Innovations, 4th ed. New York, NY: The Free Press.Rombach, H. Dieter. 1990. «Design Measurements: Some Lessons Learned.» IEEE Software, March,17–25.Rubin, Frank. 1987. «‘GOTO Considered Harmful’ Considered Harmful.» Letter to the editor.Communications of the ACM 30, no. 3 (March): 195–96. Follow-up letters in 30, no. 5 (May 1987):351–55; 30, no. 6 (June 1987): 475–78; 30, no. 7 (July 1987): 632–34; 30, no. 8 (August 1987):659–62; 30, no. 12 (December 1987): 997, 1085.Sackman, H., W. J. Erikson, and E. E. Grant. 1968. «Exploratory Experimental Studies Comparing Online and Offline Programming Performance.» Communications of the ACM 11, no. 1 (January): 3–11.Schneider, G. Michael, Johnny Martin, and W. T. Tsai. 1992. «An Experimental Study of FaultDetection in User Requirements Documents,» ACM Transactions on Software Engineering andMethodology, vol 1, no. 2, 188–204.Schulmeyer, G. Gordon. 1990. Zero Defect Software. New York, NY: McGraw-Hill.Sedgewick, Robert. 1997. Algorithms in C, Parts 1-4, 3d ed. Boston, MA: Addison-Wesley.Sedgewick, Robert. 2001. Algorithms in C, Part 5, 3d ed. Boston, MA: Addison-Wesley.Sedgewick, Robert. 1998. Algorithms in C++, Parts 1-4, 3d ed. Boston, MA: Addison-Wesley.Sedgewick, Robert. 2002. Algorithms in C++, Part 5, 3d ed. Boston, MA: Addison-Wesley.Sedgewick, Robert. 2002. Algorithms in Java, Parts 1-4, 3d ed. Boston, MA: Addison-Wesley.Sedgewick, Robert. 2003. Algorithms in Java, Part 5, 3d ed. Boston, MA: Addison-Wesley.SEI 1995. The Capability Maturity Model: Guidelines for Improving the Software Process, SoftwareEngineering Institute, Reading, MA: Addison-Wesley, 1995.SEI, 2003. «Process Maturity Profile: Software CMM®, CBA IPI and SPA Appraisal Results: 2002Year End Update,» Software Engineering Institute, April 2003.Selby, Richard W., and Victor R. Basili. 1991. «Analyzing Error-Prone System Structure.» IEEETransactions on Software Engineering SE-17, no. 2 (February): 141–52.SEN 1990. «Subsection on Telephone Systems,» Software Engineering Notes, April 1990, 11–14.Shalloway, Alan, and James R. Trott. 2002. Design Patterns Explained. Boston, MA: Addison-Wesley.Sheil, B. A. 1981. «The Psychological Study of Programming.» Computing Surveys 13, no. 1 (March):101–20.Shen, Vincent Y., et al. 1985. «Identifying Error-Prone Software—An Empirical Study.» IEEETransactions on Software Engineering SE-11, no. 4 (April): 317–24.Sheppard, S. B., et al. 1978. «Predicting Programmers’ Ability to Modify Software.» TR 78-388100-3, General Electric Company, May.Sheppard, S. B., et al. 1979. «Modern Coding Practices and Programmer Performance.» IEEEComputer 12, no. 12 (December): 41–49.Shepperd, M., and D. Ince. 1989. «Metrics, Outlier Analysis and the Software Design Process.»Information and Software Technology 31, no. 2 (March): 91–98.Shirazi, Jack. 2000. Java Performance Tuning. Sebastopol, CA: O’Reilly & Associates.Shlaer, Sally, and Stephen J. Mellor. 1988. Object Oriented Systems Analysis—Modeling the Worldin Data. Englewood Cliffs, NJ: Prentice Hall.Shneiderman, Ben, and Richard Mayer. 1979. «Syntactic/Semantic Interactions in ProgrammerBehavior: A Model and Experimental Results.» International Journal of Computer and InformationSciences 8, no. 3: 219–38. Библиография859Shneiderman, Ben. 1976. «Exploratory Experiments in Programmer Behavior.» International Journalof Computing and Information Science 5: 123–43.Shneiderman, Ben. 1980. Software Psychology: Human Factors in Computer and InformationSystems. Cambridge, MA: Winthrop.Shneiderman, Ben. 1987. Designing the User Interface: Strategies for Effective Human-ComputerInteraction. Reading, MA: Addison-Wesley.Shull, et al. 2002. «What We Have Learned About Fighting Defects,» Proceedings, Metrics 2002.IEEE; 249–258.Simon, Herbert. 1996. The Sciences of the Artificial, 3d ed. Cambridge, MA: MIT Press.Simon, Herbert. The Shape of Automation for Men and Management. Harper and Row, 1965.Simonyi, Charles, and Martin Heller. 1991. «The Hungarian Revolution.» BYTE, August, 131–38.Smith, Connie U., and Lloyd G. Williams. 2002. Performance Solutions: A Practical Guide to CreatingResponsive, Scalable Software. Boston, MA: Addison-Wesley.Software Productivity Consortium. 1989. Ada Quality and Style: Guidelines for Professional Progra-mmers. New York, NY: Van Nostrand Reinhold.Soloway, Elliot, and Kate Ehrlich. 1984. «Empirical Studies of Programming Knowledge.» IEEETransactions on Software Engineering SE-10, no. 5 (September): 595–609.Soloway, Elliot, and Sitharama Iyengar, eds. 1986. Empirical Studies of Programmers. Norwood,NJ: Ablex.Soloway, Elliot, Jeffrey Bonar, and Kate Ehrlich. 1983. «Cognitive Strategies and Looping Constructs:An Empirical Study.» Communications of the ACM 26, no. 11 (November): 853–60.Solution Systems. 1987. World-Class Programmers’ Editing Techniques: Interviews with SevenProgrammers. South Weymouth, MA: Solution Systems.Sommerville, Ian. 1989. Software Engineering, 3d ed. Reading, MA: Addison-Wesley.Spier, Michael J. 1976. «Software Malpractice—A Distasteful Experience.» Software—Practice andExperience 6: 293–99.Spinellis, Diomidis. 2003. Code Reading: The Open Source Perspective. Boston, MA: Addison-Wesley.SPMN. 1998. Little Book of Configuration Management. Arlington, VA; Software Program ManagersNetwork.Starr, Daniel. 2003. «What Supports the Roof?» Software Development. July 2003, 38–41.Stephens, Matt. 2003. «Emergent Design vs. Early Prototyping,» May 26, 2003, www.softwarereality.com/design/early_prototyping.jsp.Stevens, Scott M. 1989. «Intelligent Interactive Video Simulation of a Code Inspection.» Communi-cations of the ACM 32, no. 7 (July): 832–43.Stevens, W., G. Myers, and L. Constantine. 1974. «Structured Design.» IBM Systems Journal 13, no.2 (May): 115–39.Stevens, Wayne. 1981. Using Structured Design. New York, NY: John Wiley & Sons.Stroustrup, Bjarne. 1997. The C++ Programming Language, 3d ed. Reading, MA: Addison-Wesley.Strunk, William, and E. B. White. 2000. Elements of Style, 4th ed. Pearson.Sun Microsystems, Inc. 2000. «How to Write Doc Comments for the Javadoc Tool,» 2000. Available from http://java.sun.com/j2se/javadoc/writingdoccomments/.Sutter, Herb. 2000. Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions.Boston, MA: Addison-Wesley.Tackett, Buford D., III, and Buddy Van Doren. 1999. «Process Control for Error Free Software: ASoftware Success Story,» IEEE Software, May 1999. 860БиблиографияTenner, Edward. 1997. Why Things Bite Back: Technology and the Revenge of UnintendedConsequences. Vintage Books.Tenny, Ted. 1988. «Program Readability: Procedures versus Comments.» IEEE Transactions onSoftware Engineering SE-14, no. 9 (September): 1271–79.Thayer, Richard H., ed. 1990. Tutorial: Software Engineering Project Management. Los Alamitos,CA: IEEE Computer Society Press.Thimbleby, Harold. 1988. «Delaying Commitment.» IEEE Software, May, 78–86.Thomas, Dave, and Andy Hunt. 2002. «Mock Objects,» IEEE Software, May/June 2002.Thomas, Edward J., and Paul W. Oman. 1990. «A Bibliography of Programming Style.» ACM SigplanNotices 25, no. 2 (February): 7–16.Thomas, Richard A. 1984. «Using Comments to Aid Program Maintenance.» BYTE, May, 415–22.Tripp, Leonard L., William F. Struck, and Bryan K. Pflug. 1991. «The Application of Multiple TeamInspections on a Safety-Critical Software Standard,» Proceedings of the 4th Software EngineeringStandards Application Workshop, Los Alamitos, CA: IEEE Computer Society Press.U.S. Department of Labor. 1990. «The 1990– 91 Job Outlook in Brief.» Occupational OutlookQuarterly, Spring. U.S. Government Printing Office. Document 1990-282-086/20007.Valett, J., and F. E. McGarry. 1989. «A Summary of Software Measurement Experiences in the SoftwareEngineering Laboratory.» Journal of Systems and Software 9, no. 2 (February): 137–48.Van Genuchten, Michiel. 1991. «Why Is Software Late? An Empirical Study of Reasons for Delay inSoftware Development.» IEEE Transactions on Software Engineering SE-17, no. 6 (June): 582–90.Van Tassel, Dennie. 1978. Program Style, Design, Efficiency, Debugging, and Testing, 2d ed. EnglewoodCliffs, NJ: Prentice Hall.Vaughn-Nichols, Steven. 2003. «Building Better Software with Better Tools,» IEEE Computer,September 2003, 12–14.Vermeulen, Allan, et al. 2000. The Elements of Java Style. Cambridge University Press.Vessey, Iris, Sirkka L. Jarvenpaa, and Noam Tractinsky. 1992. «Evaluation of Vendor Products: CASETools as Methodological Companions.» Communications of the ACM 35, no. 4 (April): 91–105.Vessey, Iris. 1986. «Expertise in Debugging Computer Programs: An Analysis of the Content ofVerbal Protocols.» IEEE Transactions on Systems, Man, and Cybernetics SMC-16, no. 5 (September/October): 621–37.Votta, Lawrence G., et al. 1991. «Investigating the Application of Capture-Recapture Techniques to Requirements and Design Reviews.» Proceedings of the Sixteenth Annual Software EngineeringWorkshop, December 4–5, 1991. Greenbelt, MD: Goddard Space Flight Center. Document SEL-91-006.Walston, C. E., and C. P. Felix. 1977. «A Method of Programming Measurement and Estimation.»IBM Systems Journal 16, no. 1: 54–73.Ward, Robert. 1989. A Programmer’s Introduction to Debugging C. Lawrence, KS: R & D Publications.Ward, William T. 1989. «Software Defect Prevention Using McCabe’s Complexity Metric.» Hewlett-Packard Journal, April, 64–68.Webster, Dallas E. 1988. «Mapping the Design Information Representation Terrain.» IEEE Computer,December, 8–23.Weeks, Kevin. 1992. «Is Your Code Done Yet?» Computer Language, April, 63–72.Weiland, Richard J. 1983. The Programmer’s Craft: Program Construction, Computer Architecture,and Data Management. Reston, VA: Reston Publishing.Weinberg, Gerald M. 1983. «Kill That Code!» Infosystems, August, 48–49. 1   ...   96   97   98   99   100   101   102   103   104


вызвавший множество споров по вопросам философии науки, отличается яснос- тью, лаконичностью и включает массу интересных примеров взлетов и падений научных метафор, моделей и парадигм.
Перекрестная ссылка О выбо- ре методов проектирования и их комбинировании см. раздел 5.3.
http://cc2e.com/0285

2 0
ЧАСТЬ I Основы разработки ПО
Статья «The Paradigms of Programming». 1978 Turing Award Lecture («Communications of the ACM», August 1979, pp. 455–60) Роберта У. Флойда (Robert W. Floyd) пред- ставляет собой увлекательное обсуждение использования моделей при разработ- ке ПО; некоторые аспекты рассматриваются в ней в контексте идей Томаса Куна.
Ключевые моменты

Метафоры являются по природе эвристическими, а не алгоритмическими,
поэтому зачастую они немного небрежны.

Метафоры помогают понять процесс разработки ПО, сопоставляя его с дру- гими, более знакомыми процессами.

Некоторые метафоры лучше, чем другие.

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

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

Метафоры не исключают друг друга. Используйте комбинацию метафор, наи- более эффективную в вашем случае.

ГЛАВА 2 Метафоры, позволяющие лучше понять разработку ПО
21
Г Л А В А 3
Семь раз отмерь,
один раз отрежь:
предварительные условия
Содержание

3.1. Важность выполнения предварительных условий

3.2. Определите тип ПО, над которым работаете

3.3. Предварительные условия, связанные с определением проблемы

3.4. Предварительные условия, связанные с выработкой требований

3.5. Предварительные условия, связанные с разработкой архитектуры

3.6. Сколько времени посвятить выполнению предварительных условий?
Связанные темы

Основные решения, которые приходится принимать при конструировании:
глава 4

Влияние размера проекта на предварительные условия и процесс конструи- рования ПО: глава 27

Связь между качеством ПО и аспектами его конструирования: глава 20

Управление конструированием ПО: глава 28

Проектирование ПО: глава 5
Перед началом конструирования дома строители просматривают чертежи, про- веряют, все ли разрешения получены, и исследуют фундамент. К сооружению небоскреба, жилого дома и собачьей конуры строители готовились бы по-разно- му, но, каким бы ни был проект, перед началом конструирования они провели бы добросовестную подготовку с учетом всех особенностей проекта.
В этой главе мы рассмотрим компоненты подготовки к конструированию ПО. Как и в строительстве, конечный успех программного проекта во многом определя- ется до начала конструирования. Если фундамент ненадежен или планирование выполнено небрежно, на этапе конструирования вы в лучшем случае сможете только свести вред к минимуму.
http://cc2e.com/0309


2 2
ЧАСТЬ I Основы разработки ПО
Популярная у плотников поговорка «семь раз отмерь, один раз отрежь» очень актуальна на этапе конструирования ПО, затраты на который иногда составляют аж 65% от общего бюджета проекта. В неудачных программных проектах конст- руирование иногда приходится выполнять дважды, трижды и даже больше. Как и в любой другой отрасли, повторение самой дорогостоящей части программного проекта ни к чему хорошему привести не может.
Хотя чтение этой главы является залогом успешного конструирования ПО, само конструирование в ней не обсуждается. Если вы уже хорошо разбираетесь в цик- ле разработки ПО или вам не терпится добраться до обсуждения конструирова- ния, можете перейти к главе 5. Если вам не нравится идея выполнения предвари- тельных условий конструирования, просмотрите раздел 3.2, чтобы узнать, какую роль они играют в вашем случае, а затем вернитесь к разделу 3.1, в котором опи- сываются расходы, связанные с их невыполнением.
3.1. Важность выполнения предварительных
условий
Общей чертой всех программистов, создающих высокока- чественное ПО, является использование высококачествен- ных методов, ставящих ударение на качестве ПО в самом начале, середине и конце проекта.
Если вы подчеркиваете качество в конце проекта, это при- ходится на этап тестирования системы. Именно о тестиро- вании думают многие люди, представляя процесс гарантии качества ПО, но тести- рование — только один из компонентов стратегии гарантии качества, и не самый важный. Тестирование не позволяет обнаружить такие ошибки, как создание не того приложения или создание нужного приложения не тем образом; эти ошибки дол- жны быть определены и устранены раньше — до начала конструирования.
Если вы уделяете повышенное внимание качеству в середине работы над проектом, вы подчеркиваете методы конструирования, которым и посвя- щена большая часть этой книги.
Если вы подчеркиваете качество в начале проекта, вы качественно выполняете пла- нирование, определение требований и проектирование. Если вы спроектирова- ли автомобиль «Понтиак Ацтек», то сколько бы вы его ни тестировали, он никог- да не превратится в «Роллс-Ройс». Вы можете создать самый лучший «Ацтек», но если вам нужен «Роллс-Ройс», это нужно планировать с самого начала. При раз- работке ПО такому планированию соответствуют определение проблемы и определение и проектирование решения.
Конструирование — средний этап работы, поэтому ко времени начала конструи- рования успех проекта уже частично предопределен. И все же во время констру- ирования вы хотя бы должны быть в состоянии определить, насколько благопо- лучна ваша ситуация, и вернуться назад, если на горизонте показались черные тучи неудачи. В оставшейся части этой главы я подробно расскажу, почему адекватная подготовка к конструированию так важна и как определить, действительно ли вы готовы перейти к нему.
Перекрестная ссылка Повыше- ние внимания к качеству ПО —
самый эффективный способ повышения производительнос- ти труда программистов. (см.
раздел 20.5).


ГЛАВА 3 Семь раз отмерь, один раз отрежь: предварительные условия
23
Актуальны ли предварительные условия
для современных программных проектов?
Порой говорят, что предварительные действия, такие как разработка архитектуры, проектирование и планирование проекта, в современных условиях бесполезны. Такие заяв- ления не подтверждаются ни прошлыми, ни современны- ми исследованиями (подробности см. ниже). Оппоненты предварительных условий обычно приводят примеры не- удачного выполнения предварительных условий и делают вывод, что такая работа неэффективна. Тем не менее под- готовку к конструированию можно выполнить успешно, и данные, накопленные с 1970-х, свидетельствуют о том, что в таких случаях работа над проектом оказывается эффективнее.
Общая цель подготовки — снижение риска: адекватное планирование позволяет исключить главные аспекты риска на самых ранних стадиях работы, чтобы основную часть проекта можно было выполнить макси- мально эффективно. Безусловно, главные факторы риска в создании ПО — неудач- ная выработка требований и плохое планирование проекта, поэтому подготовка направлена в первую очередь на оптимизацию этих этапов.
Так как подготовка к конструированию не является точной наукой, специфиче- ский подход к снижению риска будет в значительной степени определяться осо- бенностями проекта (см. раздел 3.2).
Причины неполной подготовки
Возможно, вам кажется, что все профессионалы знают о важности подготовки и всегда до начала конструирования проверяют выполнение предварительных ус- ловий. Увы, это не так.
Зачастую причина неполной подготовки к конструированию
ПО объясняется тем, что отвечающие за нее разработчики не имеют нужного опыта. Для планирования проекта, созда- ния адекватной бизнес-модели, разработки полных и точ- ных требований и высококачественной архитектуры нуж- но обладать далеко не тривиальными навыками, однако большинство разработчиков этому не обучены. Если разра- ботчики не знают, как выполнять предварительную работу,
рекомендация «выполнять больше такой работы» не имеет смысла: если работа изначально выполняется некачествен- но, ее выполнение в
больших объемах не принесет никакой пользы! Объяснение выполнения этих действий не является предметом данной книги, однако в разде- ле «Дополнительные ресурсы» в конце главы я привел массу источников, позво- ляющих получить такой опыт.
Некоторые программисты умеют готовиться к конструированию, но пренебрега- ют подготовкой, потому что не могут устоять перед искушением пораньше при- ступить к кодированию. Если вы принадлежите к их числу, могу дать два совета.
Первый: прочитайте следующий раздел. Возможно, у вас откроются глаза на не-
Выбор методологии не должен быть невежественным. Она дол- жна быть основана на самом но- вом и эффективном и дополне- на старым и заслуживающим доверия.
Харлан Миллз
(Harlan Mills)
http://cc2e.com/0316
Дополнительные сведения О про- фессиональной программе разра- ботки ПО, поощряющей приме- нение этих навыков, см. главу 16
книги «Professional Software Deve- lopment» (McConnell, 2004).


2 4
ЧАСТЬ I Основы разработки ПО
которые вещи. Второй: уделяйте внимание проблемам, с которыми сталкиваетесь.
Поработав над несколькими крупными программами, вы прекрасно поймете пользу заблаговременного планирования. Положитесь на свой опыт.
Наконец, еще одна причина пренебрежения подготовкой к конструированию со- стоит в том, что менеджеры прохладно относятся к программистам, которые тра- тят на это время. Это довольно странно: такие люди, как Барри Бом (Barry Boehm),
Гради Буч (Grady Booch) и Карл Вигерс (Karl Wiegers), отстаивают важность выра- ботки требований и проектирования уже 25 лет, и менеджеры, казалось бы, уже должны понимать, что разработка ПО не ограничивается кодированием, но...
Несколько лет назад я работал над проектом Минобороны,
и как-то на этапе выработки требований нас посетил кура- тор проекта — генерал. Мы сказали ему, что работаем над требованиями: большей частью общаемся с клиентами,
определяем их потребности и разрабатываем проект при- ложения. Он, однако, настаивал на том, чтобы увидеть код.
Мы сказали, что у нас нет кода, и тогда он отправился в ра- бочий отдел, намереваясь хоть кого-нибудь из 100 человек поймать за програм- мированием. Огорченный тем, что почти все из них находились не за своими ком- пьютерами, этот крупный человек наконец указал на инженера рядом со мной и проревел: «А он что делает? Он ведь пишет код!» Вообще-то этот инженер рабо- тал над утилитой форматирования документов, но генерал хотел увидеть код, нашел что-то похожее на него и хотел, чтобы хоть кто-то писал код, так что мы сказали ему, что он прав: это код.
Этот феномен известен как синдром WISCA или WIMP: «Why Isn’t Sam Coding
Anything? (Почему Сэм не пишет код?)» или «Why Isn’t Mary Programming (Почему
Мэри не программирует)?»
Если менеджер проекта претендует на роль бригадного генерала и приказывает вам немедленно начать программировать, вы можете с легкостью ответить: «Есть,
сэр!» (И впрямь, какое вам дело? Умудренные опытом ветераны должны отвечать за свои слова.) Это плохой ответ, и у вас есть несколько лучших вариантов. Во- первых, вы можете решительно отвергнуть неэффективную методику работы. Если у вас нормальные отношения с начальником и все в порядке с банковским сче- том, это может сработать.
Во-вторых, вы можете притвориться, что работаете над кодом. Разложите на сто- ле листинги старой программы и продолжайте работать над требованиями и ар- хитектурой как ни в чем не бывало. Так вы выполните проект быстрее и качествен- нее. Порой этот подход находят неэтичным, но начальник-то останется доволен!
В-третьих, вы можете посвятить руководителя в нюансы технических проектов.
Это хороший подход, потому что он увеличивает число грамотных руководите- лей в мире. В следующем подразделе приведено подробное обоснование важно- сти выполнения предварительных условий до начала конструирования.
Наконец, вы можете найти другую работу. Независимо от экономических подъе- мов и спадов хороших программистов всегда не хватает (BLS, 2002), а жизнь слиш- ком коротка, чтобы тратить ее на работу в отсталом учреждении при наличии множества лучших вариантов.
Дополнительные сведения Ряд интересных вариаций на эту тему см. в классическом труде
Джеральда Вайнберга «The Psy- chology of Computer Program- ming» (Weinberg, 1998).


ГЛАВА 3 Семь раз отмерь, один раз отрежь: предварительные условия
25
Самый веский аргумент в пользу выполнения
предварительных условий перед началом конструирования
Допустим, вы уже забрались на гору определения проблемы, прошли милю по пути выработки требований, сбросили грязную одежду у фонтана архитектуры и ис- купались в чистых водах подготовленности. Следовательно, вы знаете, что перед реализацией системы нужно понимать, что и как она будет делать.
Один из аспектов профессии разработчика — посвящение профанов в осо- бенности процесса разработки ПО. Этот раздел поможет вам в общении с менеджерами и руководителями, еще блуждающих во тьме. В нем под- робно описан веский аргумент в пользу адекватного определения требований и проектирования архитектуры до начала кодирования, тестирования и отладки. Изу- чите его, сядьте перед начальником и поговорите о процессе программирования по душам.
Обращение к логике
Подготовка к проекту — одно из главных условий эффективного программирова- ния, и это логично. Объем планирования зависит от масштаба проекта. С управ- ленческой точки зрения, планирование подразумевает определение сроков, числа людей и компьютеров, необходимых для выполнения работ. С технической — пла- нирование подразумевает получение представления о создаваемой системе, позво- ляющего не истратить деньги на создание неверной системы. Иногда пользовате- ли не четко знают, что желают получить, и для определения их требований может понадобиться больше усилий, чем хотелось бы. Как бы то ни было, это дешевле, чем создать не то, что нужно, похерить результат и начать все заново.
До начала создания системы не менее важно подумать и о том, как вы собирае- тесь ее создавать. Никому не хочется тратить время и деньги на бесплодные блуж- дания по лабиринту.
Обращение к аналогии
Создание программной системы похоже на любой другой проект, требующий людских и финансовых ресурсов. Возведение дома начинается не с забивания гвоздей, а с создания, анализа и утверждения чертежей. При разработке ПО на- личие технического плана означает не меньше.
Никто не наряжает новогоднюю елку, не установив ее. Никто не разводит огонь,
не открыв дымоход. Никто не отправляется в долгий путь с пустым бензобаком.
Никто не принимает душ в одежде и не надевает носки после обуви. И т. д., и т. п.
Программисты — последнее звено пищевой цепи разработки ПО. Архитекторы поглощают требования, проектировщики потребляют архитектуру, а программи- сты — проект приложения.
Сравните пищевую цепь разработки ПО с реальной пищевой цепью. В экологи- чески чистой среде водные жучки служат пищей рыбам, которыми в свою оче- редь питаются чайки. Это здоровая пищевая цепь. Если на каждом этапе разра- ботки ПО у вас будет здоровая пища, результатом станет здоровый код, написан- ный довольными программистами.