Файл: Руководство по стилю программирования и конструированию по.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 30.11.2023
Просмотров: 756
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
ГЛАВА 19 Общие вопросы управления
451
Одной из единиц измерения «программной сложности» яв- ляется число воображаемых объектов, которые вам прихо- дится одновременно держать в уме, чтобы разобраться в программе. Это умственное жонглирование — один из са- мых сложных аспектов программирования и причина того,
что программирование требует большей сосредоточенности, чем другие виды деятельности. По этой причине программисты не любят, когда их «ненадолго прерывают» — такие перерывы равносильны просьбе жонглеру продолжать под- кидывать три мяча и подержать вашу сумку с продуктами.
Интуитивно понятно, что сложность программы во многом определя- ется количеством усилий, требуемых для ее понимания. Том Маккейб (Tom
McCabe) опубликовал важную статью, утверждающую, что сложность про- граммы определяется ее управляющей логикой (1976). Другие исследователи об- наружили дополнительные факторы, кроме предложенного Маккейбом циклома- тического показателя сложности (например, количество переменных, использу- емых в программе), но они согласны, что управляющая логика — одна из глав- ных составляющих сложности, если не самая главная.
Насколько важна сложность?
Исследователи в области вычислительной техники уже на протяжении двух десятилетий осознают важность пробле- мы сложности. Много лет назад Дейкстра предупреждал об опасности сложности: «Компетентный программист полно- стью осознает строго ограниченные размеры своего чере- па, поэтому подходит к задачам программирования со всей возможной скромно- стью» (Dijkstra, 1972). Из этого не следует, что вам нужно увеличить объем ваше- го черепа, чтобы иметь дело с невероятной сложностью. Это предполагает, что вы можете никогда не связываться с чрезмерной сложностью и всегда должны пред- принимать шаги для ее уменьшения.
Сложность управляющей логики имеет большое значение, потому что она коррелирует с низкой надежностью и частыми ошибками (McCabe, 1976,
Shen et al., 1985). Вильям Т. Уорд (William T. Ward) сообщал о значитель- ном выигрыше в надежности ПО, полученном в Hewlett-Packard в результате при- менения показателя сложности Маккейба (1989b). Этот показатель использовал- ся для идентификации проблемных участков в одной программе длиной 77 000
строк. Коэффициент ошибок после выпуска этой программы составил 0,31 ошибку на 1000 строк кода. Коэффициент ошибок в программе длиной 125 000 строк не превышал 0,02 ошибки на 1000 строк кода. Ворд отметил, что из-за своей мень- шей сложности обе программы имели значительно меньше дефектов, чем другие программы в Hewlett-Packard. Моя компания Construx Software в 2000 г. получила похожие результаты при использовании средств измерения сложности для поис- ка проблемных методов.
Делайте вещи настолько про- стыми, насколько это возмож- но, но не проще.
Альберт Эйнштейн
Перекрестная ссылка О сложно- сти см. подраздел «Главный Тех- нический Императив ПО: управ- ление сложностью» раздела 5.2.
452
ЧАСТЬ IV Операторы
Общие принципы уменьшения сложности
Вы можете бороться со сложностью двумя способами. Во-первых, вы можете улуч- шить свои способности к умственному жонглированию, выполняя специальные упражнения. Но программирование само по себе — уже хорошее упражнение, а люди, похоже, сталкиваются с трудностями при жонглировании б
ó
льшим коли- чеством, чем от пяти до девяти воображаемых сущностей (Miller, 1956). Так что потенциал улучшения невелик. Во-вторых, вы можете уменьшить сложность ва- ших программ и количество усилий, прилагаемых для их понимания.
Как измерить сложность
У вас, возможно, есть интуитивное ощущение того, что де- лает метод более или менее сложным. Исследователи пыта- ются формализовать свои чувства и приводят несколько способов измерения сложности. Возможно, самый важный способ предложил Том Маккейб, Сложность в нем измеря- ется с помощью подсчета количества «точек принятия решения» в методе
(табл. 19-2):
Табл. 19-2. Способы подсчета точек принятия решения в методе
1. Начните считать с 1 на некотором участке кода.
2. Добавляйте 1 для каждого из следующих ключевых слов или их эквивалентов:
if while repeat for and or.
3. Добавляйте 1 для каждого варианта в операторе
case.
Приведем пример:
if ( ( (status = Success) and done ) or
( not done and ( numLines >= maxLines ) ) ) then ...
В этом фрагменте вы начинаете считать с 1, получаете 2 для
if, 3 — для and, 4 —
для
or и 5 — для and. Таким образом, этот фрагмент содержит всего пять точек принятия решения.
Что делать с этим измерением сложности
Посчитав количество точек принятия решения, вы можете использовать это чис- ло для анализа сложности вашего метода:
0–5
Этот метод, возможно, в порядке.
6–10
Начинайте думать о способах упрощения метода.
10+
Вынесите часть кода в отдельный метод и вызывайте его.
Перенос части метода в другой метод не упрощает программу — он просто пере- мещает точки принятия решения. Но он уменьшает сложность, с которой вам при- ходится иметь дело в каждый момент времени. Поскольку одна из главных целей состоит в минимизации количества элементов, которыми приходится мысленно жонглировать, то уменьшение сложности отдельного метода дает свой результат.
Дополнительные сведения Опи- санный здесь подход основан на важной статье Тома Маккейба
«A Complexity Measure» (1976).
ГЛАВА 19 Общие вопросы управления
453
Максимум в 10 точек принятия решения не является абсолютным ограничением.
Используйте количество этих точек как сигнал, предупреждающий о том, что метод,
возможно, стоит перепроектировать. Не считайте его неколебимым правилом.
Оператор
case со многими вариантами может иметь более 10 элементов, но в зависимости от назначения
case может быть глупо разбивать его на части.
Другие виды сложности
Измерение сложности, предложенное Маккейбом, — не единственный значимый показатель, но он наиболее широко обсуждался в компьютерной литературе и особенно поле- зен при рассмотрении управляющей логики. Другие пока- затели включают количество используемых данных, число уровней вложенности в управляющих конструкциях, число строк кода, число строк между успешными обращениями к переменной («диапа- зон»), число строк, в которых используется переменная («время жизни») и объем ввода и вывода. Некоторые исследователи разработали составные показатели слож- ности, основанные на сочетании перечисленных простых вариантов.
Контрольный список: вопросы
по управляющим структурам
Используют ли выражения идентификаторы true и false,
а не 1 и 0?
Сравниваются ли логические значения с true и false неявно?
Сравниваются ли числовые значения со своими тестовыми значениями явно?
Выполнено ли упрощение выражений с помощью введения новых логиче- ских переменных, использования логических функций и таблиц решений?
Составлены ли логические выражения позитивно?
Сбалансированы ли пары скобок?
Используются ли скобки везде, где они необходимы для большей ясности?
Заключены ли логические выражения в скобки целиком?
Написаны ли условия в соответствии с расположением чисел на числовой прямой?
Используются ли в программах на Java выражения вида a.equals(b), а не
a == b там, где это необходимо?
Очевидно ли применение пустых операторов?
Выполнено ли упрощение глубоко вложенных выражений с помощью повтор- ной проверки части условия, преобразования в операторы if-then-else или
case, перемещения части кода в отдельные методы, преобразования с ис- пользованием более обеъктно-ориентированной модели или они были улуч- шены как-то иначе?
Если метод содержит более 10 точек принятия решения, есть ли хорошая причина, чтобы не перепроектировать его?
Дополнительные сведения Отлич- ное обсуждение показателей сложности см. в «Software En–
gineering Metrics and Models»
(Conte, Dunsmore and Shen, 1986).
http://cc2e.com/1985
454
ЧАСТЬ IV Операторы
Ключевые моменты
쐽
Упрощение и облегчение чтения логических выражений вносит существенный вклад в качество вашего кода.
쐽
Глубокая вложенность затрудняет понимание метода. К счастью, вы сравнитель- но легко можете ее избежать.
쐽
Структурное программирование — это простая, но все еще злободневная идея:
вы можете построить любую программу с помощью комбинации последова- тельностей, выборов и итераций.
쐽
Уменьшение сложности — ключ к написанию высококачественного кода.
1 ... 51 52 53 54 55 56 57 58 ... 104
ГЛАВА 19 Общие вопросы управления
455
Часть V
УСОВЕРШЕНСТВОВАНИЕ
КОДА
쐽
Глава 20. Качество ПО
쐽
Глава 21. Совместное конструирование
쐽
Глава 22. Тестирование, выполняемое разработчиками
쐽
Глава 23. Отладка
쐽
Глава 24. Рефакторинг
쐽
Глава 25. Стратегии оптимизации кода
쐽
Глава 26. Методики оптимизации кода
456
ЧАСТЬ V Усовершенствование кода
Г Л А В А 2 0
Качество ПО
Содержание
쐽
20.1. Характеристики качества ПО
쐽
20.2. Методики повышения качества ПО
쐽
20.3. Относительная эффективность методик контроля качества ПО
쐽
20.4. Когда выполнять контроль качества ПО?
쐽
20.5. Главный Закон Контроля Качества ПО
Связанные темы
쐽
Совместное конструирование: глава 21
쐽
Тестирование, выполняемое разработчиками: глава 22
쐽
Отладка: глава 23
쐽
Предварительные условия конструирования: главы 3 и 4
쐽
Актуальность предварительных условий для современных программных про- ектов: соответствующий подраздел раздела 3.1
В этой главе мы рассмотрим методики повышения качества ПО в контексте кон- струирования. Конечно, вся эта книга посвящена повышению качества ПО, но в данной главе вопросы качества и контроля качества обсуждаются более целена- правленно. Темой этой главы являются скорее общие вопросы, а не практичес- кие методики контроля качества. Практические советы, касающиеся совместной разработки, а также тестирования и отладки, можно найти в трех следующих главах.
20.1. Характеристики качества ПО
Качество ПО имеет внешние и внутренние характеристики. К внешним характе- ристикам относятся свойства, которые осознает пользователь программы. Они описаны ниже.
쐽
Корректность — отсутствие/наличие дефектов в спецификации, проекте и реализации системы.
쐽
Практичность — легкость изучения и использования системы.
http://cc2e.com/2036
ГЛАВА 20 Качество ПО
457
쐽
Эффективность — степень использования системных ресурсов. Эта характе- ристика учитывает такие факторы, как быстродействие приложения и требуе- мый им объем памяти.
쐽
Надежность — способность системы выполнять необходимые функции в пред- определенных условиях; средний интервал между отказами.
쐽
Целостность — способность системы предотвращать неавторизованный или некорректный доступ к своим программам и данным. Идея целостности под- разумевает ограничение доступа к системе для неавторизованных пользова- телей, а также обеспечение правильности доступа к данным, т. е. одновремен- ное изменение взаимосвязанных данных, хранение только допустимых значе- ний и т. д.
쐽
Адаптируемость — возможность использования системы без ее изменения в тех областях или средах, на которые она не была ориентирована непосред- ственно.
쐽
Правильность — степень безошибочности системы, особенно в отношении вывода количественных данных. Правильность характеризует выполнение системой ее функций, а не то, создана ли она корректно. Этим правильность отличается от корректности.
쐽
Живучесть — способность системы продолжать работу при вводе недопус- тимых данных или в напряженных условиях.
Некоторые из этих характеристик перекрываются, однако каждая имеет свои отли- чительные черты, которые в одних случаях выражены сильнее, а в других слабее.
Внешние характеристики — единственная категория свойств ПО, которая волну- ет пользователей. Пользователей беспокоит легкость работы с ПО, а не легкость его изменения. Их заботит корректность ПО, а не удобочитаемость или структи- рованность кода.
Программистов волнуют и внешние характеристики ПО, и внутренние. Раз уж эта книга посвящена программированию, основное внимание в ней уделяется внут- ренним характеристикам качества, которые перечислены ниже.
쐽
Удобство сопровождения — легкость изменения программной системы с це- лью реализации дополнительных возможностей, повышения быстродействия,
исправления дефектов и т. д.
쐽
Гибкость — возможный масштаб изменения системы с целью использования ее в тех областях или средах, на которые она не была непосредственно ори- ентирована.
쐽
Портируемость — легкость изменения системы с целью использования в сре- дах, на которые она не была ориентирована непосредственно.
쐽
Возможность повторного использования — масштабность и легкость ис- пользования частей системы в других системах.
쐽
Удобочитаемость — легкость чтения и понимания исходного кода системы,
особенно на детальном уровне отдельных операторов.
쐽
Тестируемость — возможная степень выполнения блочного и системного те- стирования программы и проверки ее соответствия требованиям.