Главная страница
Навигация по странице:

  • Повторите нужное число раз

  • Разработка с изначальными тестами

  • Проектирование по контракту

  • ЧАСТЬ II

  • Контрольный список: Процесс Программирования с Псевдокодом

  • ПЕРЕМЕННЫЕ Глава 10.

  • ЧАСТЬ III

  • 10.1. Что вы знаете о данных

  • Общее число баллов 232ЧАСТЬ III

  • 10.2. Грамотное объявление переменных

  • Отключите неявные объявления

  • Объявляйте все переменные

  • Используйте конвенции именования

  • Проверяйте имена переменных

  • 10.3. Принципы инициализации переменных

  • Перекрестная ссылка

  • Инициализируйте каждую переменную при ее объявлении

  • Пример инициализации массива при его объявлении (C++) float studentGrades[ MAX_STUDENTS ] = { 0.0 }; Инициализируйте каждую переменную там, где она

  • Пример плохой инициализации переменных (Visual Basic)

  • Совершенный код. Совершенный код. Мастер-класс. Стив Макконнелл. Руководство по стилю программирования и конструированию по


    Скачать 5.88 Mb.
    НазваниеРуководство по стилю программирования и конструированию по
    АнкорСовершенный код
    Дата31.03.2023
    Размер5.88 Mb.
    Формат файлаpdf
    Имя файлаСовершенный код. Мастер-класс. Стив Макконнелл.pdf
    ТипРуководство
    #1028502
    страница31 из 106
    1   ...   27   28   29   30   31   32   33   34   ...   106
    ГЛАВА 9 Процесс программирования с псевдокодом
    225
    
    Проверьте общее качество конструкции. Убедитесь, что метод выполняет един#
    ственную задачу и делает это хорошо, имея в виду его слабое сопряжение с другими методами и проектирование в соответствии с методикой защитного программирования (см. главу 7).
    
    Проверьте переменные метода: корректность их именования, неиспользуемые объекты, необъявленные переменные, неверно инициализированные объек#
    ты и т. д. (см. главы 10–13).
    
    Проверьте логику метода. Проанализируйте наличие ошибок занижения/завы#
    шения на 1, некорректной вложенности и утечки ресурсов (см. главы 14–19).
    
    Проверьте форматирование метода. Убедитесь в корректном использовании пробелов для структурирования метода, выражений и списка параметров (см.
    главу 31).
    
    Проверьте документирование метода. Убедитесь в корректности псевдокода,
    переведенного в комментарии. Проверьте описание алгоритма, документиро#
    вание интерфейса, неочевидных зависимостей и нестандартных подходов (см.
    главу 32).
    
    Удалите лишние комментарии. Иногда комментарии, полученные из псевдо#
    кода, являются избыточными, особенно когда ППП применяется рекурсивно и комментарии лишь описывают вызов метода, назначение которого и так понятно из его имени.
    Повторите нужное число раз
    Если качество метода неудовлетворительное, вернитесь к псевдокоду. Создание высококачественного ПО — итеративный процесс, так что без колебаний повто#
    ряйте весь цикл конструирования вновь и вновь.
    9.4. Альтернативы ППП
    Для меня ППП — идеальная методика создания классов и методов. Другие специ#
    алисты рекомендуют иные подходы. Вы можете применять их как альтернативу или дополнение ППП.
    Разработка с изначальными тестами Это популярный стиль разработки, при котором тестовые задания пишутся до самого кода (см. раздел 22.2). Есть хорошая книга Кента Бека на эту тему — «Test#Driven Development: By Example» (Beck, 2003).
    Рефакторинг Рефакторинг — это подход к разработке с усовершенствовани#
    ем кода посредством последовательности семантически корректных преобразо#
    ваний. Программисты пользуются шаблонами плохого кода или «запахами» (smells)
    для выявления разделов кода, подлежащих усовершенствованию. Этот подход по#
    дробно описан в главе 24, а также в книге Мартина Фаулера «Refactoring: Improving the Design of Existing Code» (Fowler, 1999).
    Проектирование по контракту Это подход предполагает, что каждый метод имеет пред# и постусловия (см. раздел 8.2). Лучший источник информации на эту тему — книга Бертрана Мейера «Object#Oriented Software Construction» (Meyer, 1997).

    226
    ЧАСТЬ II Высококачественный код
    Бессистемное программирование Некоторые программисты лепят программу как попало, а не используют тот или иной систематический подход, например ППП.
    Если вы не понимаете, что делать дальше, это признак того, что надо переходить на ППП. Не было ли у вас такого, чтобы вы забывали написать часть класса или метода? Вряд ли такое могло случиться при применении ППП. Если вы глядите на экран и не знаете, с чего начать, пора начать ППП, который сделает вашу про#
    граммистскую долю проще.
    Контрольный список: Процесс Программирования
    с Псевдокодом
    
    Проверили ли вы, что удовлетворяются предваритель- ные условия?
    
    Определена ли проблема, которую решает класс?
    
    Достаточно ли понятна высокоуровневая конструкция,
    чтобы дать классам и методам адекватные имена?
    
    Продумали ли вы тестирование класса и каждого из его методов?
    
    Рассматривали ли вы эффективность с позиции стабиль- ных интерфейсов и понятной реализации или с позиции соответствия ресурсам и бюджету?
    
    Проанализировали ли вы стандартные и другие библиотеки на предмет наличия подходящих методов и компонентов?
    
    Просмотрели ли вы литературу в поисках полезных алгоритмов?
    
    Проектировали ли вы каждый метод с использованием подробного псевдо- кода?
    
    Проверили ли вы псевдокод умозрительно? Легко ли его понять?
    
    Уделили ли вы внимание предупреждениям, которые указывают на необхо- димость перепроектирования (использование глобальных данных, операции,
    которые лучше перенести в другой класс или метод и т. д.)?
    
    Точно ли вы перевели псевдокод в код?
    
    Рекурсивно ли вы применяли ППП, разбивая методы на более мелкие при необходимости?
    
    Документировали ли вы принимаемые допущения?
    
    Убрали ли вы избыточные комментарии?
    
    Проделали ли вы несколько итераций или остановились после первой?
    
    Вполне ли вы понимаете свой код? Легко ли в нем разобраться?
    Ключевые моменты
    
    Конструирование классов и методов — процесс итеративный. Особенности,
    замечаемые при конструировании отдельных методов, заставляют возвращаться к проектированию класса.
    
    Написание хорошего псевдокода предполагает употребление понятного есте#
    ственного языка без специфических особенностей конкретного языка програм#
    мирования, а также формулировок на уровне намерений (описания сути кон#
    струкции, а не способов ее работы).
    http://cc2e.com/0943
    Перекрестная ссылка Назначе- ние этого списка — проверить,
    применяете ли вы правильные методики при создании мето- дов. Контрольный список по качеству методов как таковых см. в главе 7.

    ГЛАВА 9 Процесс программирования с псевдокодом
    227
    
    Процесс Программирования с Псевдокодом — полезный инструмент деталь#
    ного проектирования, упрощающий кодирование. Псевдокод транслируется непосредственно в комментарии, гарантируя их адекватность и полезность.
    
    Не останавливайтесь на первой придуманной вами конструкции — испробуй#
    те несколько подходов и выберите лучший, прежде чем писать код.
    
    Проверяйте свою работу на каждом шаге и просите об этом других. При этом вы отловите ошибки на наименее дорогостоящем уровне, когда вы вложили в работу меньше усилий.

    ГЛАВА 10 Общие принципы использования переменных
    229
    Часть III
    ПЕРЕМЕННЫЕ
    
    Глава 10. Общие принципы использования переменных
    
    Глава 11. Сила имен переменных
    
    Глава 12. Основные типы данных
    
    Глава 13. Нестандартные типы данных

    230
    ЧАСТЬ III Переменные
    Г Л А В А 1 0
    Общие принципы
    использования переменных
    Содержание
    
    10.1. Что вы знаете о данных?
    
    10.2. Грамотное объявление переменных
    
    10.3. Принципы инициализации переменных
    
    10.4. Область видимости
    
    10.5. Персистентность
    
    10.6. Время связывания
    
    10.7. Связь между типами данных и управляющими структурами
    
    10.8. Единственность цели каждой переменной
    Связанные темы
    
    Именование переменных: глава 11
    
    Фундаментальные типы данных: глава 12
    
    Редкие типы данных: глава 13
    
    Размещение объявлений данных: одноименный подраздел раздела 31.5
    
    Документирование переменных: подраздел «Комментирование объявлений данных» раздела 32.5
    Если при конструировании приходится заполнять небольшие пробелы в требо#
    ваниях и архитектуре, это нормально и даже желательно. Проектирование про#
    граммы вплоть до микроскопических деталей было бы неэффективным. В этой главе рассматривается один из низкоуровневых вопросов конструирования —
    использование переменных.
    Эта глава будет особенно полезна опытным программистам. Довольно часто мы применяем рискованные подходы, не имея полного представления об альтерна#
    тивах, а после используем их в силу привычки. Особый интерес для опытных программистов могут представлять разделы 10.6 и 10.8, посвященные соответствен#
    http://cc2e.com/1085

    ГЛАВА 10 Общие принципы использования переменных
    231
    но времени связывания и использованию переменных только с одной целью. Если вы не знаете, насколько «опытным» программистом вы являетесь, пройдите «Тест на знание типов данных» в разделе 10.1 и узнайте.
    В этой главе я буду понимать под «переменными» и объекты, и встроенные типы данных, такие как целые числа и массивы. «Типами данных» я, как правило, буду называть встроенные типы данных, а просто «данными» — и встроенные типы данных, и объекты.
    10.1. Что вы знаете о данных?
    Создавая данные, вы должны в первую очередь понять, какие именно данные вам нужны. Обширные знания о разных типах данных — важней#
    ший компонент в инструментарии любого программиста. Введения в типы данных в этой книге вы не найдете, но «Тест на знание данных» поможет вам определить, сколько еще вам нужно о них узнать.
    Тест на знание данных
    Поставьте себе
    1 балл за каждый термин, который вам известен. Если термин ка#
    жется знакомым, но вы не уверены в его значении, поставьте себе
    0,5 балла. Вы#
    полнив тест, просуммируйте баллы и оцените результат по приведенному ниже описанию.
    ______ abstract data type
    ______ literal (литерал)
    (абстрактный тип данных)
    ______ array (массив)
    ______ local variable (локальная переменная)
    ______ bitmap (растровое изображение)
    ______ lookup table (таблица поиска)
    ______ boolean variable (булева переменная)
    ______ member data (данные#члены)
    ______ B#tree (B#дерево)
    ______ pointer (указатель)
    ______ character variable
    ______ private (закрытый)
    (символьная переменная)
    ______ container class (класс#контейнер)
    ______ retroactive synapse (ретроактивный синапс)
    ______ double precision (двойная точность)
    ______ referential integrity (целостность ссылочных данных)
    ______ elongated stream (удлиненный поток) ______ stack (стек)
    ______ enumerated type (перечисление)
    ______ string (строка)
    ______ floating point (число
    ______ structured variable с плавающей точкой)
    (структурная переменная)
    ______ heap (куча)
    ______ tree (дерево)
    ______ index (индекс)
    ______ typedef (синоним типа)
    ______ integer (целое число)
    ______ union (объединение)
    ______ linked list (связанный список)
    ______ value chain (цепочка начисления стоимости)
    ______ named constant
    ______ variant (универсальный тип)
    (именованная константа)
    ______ Общее число баллов

    232
    ЧАСТЬ III Переменные
    Интерпретировать результаты можно примерно так.
    0–14
    Вы — начинающий программист; возможно, вы учитесь на первом курсе ин#
    ститута или самостоятельно изучаете свой первый язык программирования.
    Вы можете многое узнать, прочитав одну из книг, перечисленных в следующем подразделе. Вернувшись к этой части книги потом, вы извлечете больше пользы, потому что этот материал адресован более опытным программистам.
    15–19
    Вы — программист среднего уровня или опытный программист, который мно#
    гое забыл. Из книг, указанных чуть ниже, вы также сможете извлечь выгоду,
    хотя многие концепции будут вам знакомы.
    20–24
    Вы — эксперт в программировании. Вероятно, на вашей полке уже стоят книги,
    указанные ниже.
    25–29
    Вы знаете о типах данных больше, чем я. Может, напишете собственную книгу
    (пришлите мне экземпляр!)?
    30–32
    Вы — тщеславный мошенник. Термины «удлиненный поток», «ретроактивный синапс» и «цепочка начисления стоимости» не имеют никакого отношения к типам данных — я их выдумал! Прочитайте раздел «Профессиональная чест#
    ность» в главе 33!
    Дополнительные ресурсы
    Хорошими источниками информации о типах данных являются следующие книги:
    Cormen, H. Thomas, Charles E. Leiserson, Ronald L. Rivest.
    Introduction to Algorithms.
    New York, NY: McGraw Hill. 1990.
    Sedgewick, Robert.
    Algorithms in C++, Parts 1%4, 3d ed. Boston, MA: Addison#Wesley, 1998.
    Sedgewick, Robert.
    Algorithms in C++, Part 5, 3d ed. Boston, MA: Addison#Wesley, 2002.
    10.2. Грамотное объявление переменных
    В этом разделе описаны способы оптимизации объявления переменных. Строго говоря, это не такая уж и крупная за#
    дача, и вы могли бы подумать, что она не заслуживает соб#
    ственного раздела. И все же создавать переменные прихо#
    дится очень часто, и приобретение правильных привычек поможет вам сэкономить время и исключить ненужные разочарования.
    Неявные объявления
    Некоторые языки поддерживают неявное объявление переменных. Так, если, про#
    граммируя на Microsoft Visual Basic, вы попытаетесь использовать необъявленную переменную, компилятор может автоматически объявить ее для вас (это зависит от параметров компилятора).
    Неявное объявление переменных — одна из самых опасных возможностей язы#
    ка. Если вы программировали на Visual Basic, то знаете, как жаль времени, потра#
    ченного на поиск причины неправильного значения
    acctNo, если в итоге обнару#
    живается, что вы по ошибке вызвали переменную
    acctNum, которая была иници#
    ализирована нулем. Если язык не заставляет объявлять переменные, подобную ошибку допустить очень легко.
    Перекрестная ссылка О форма- тировании объявлений перемен- ных см. одноименный подраз- дел раздела 31.5, а о докумен- тировании — подраздел «Ком- ментирование объявлений дан- ных» раздела 32.5.

    ГЛАВА 10 Общие принципы использования переменных
    233
    Если язык требует объявления переменных, для столкновения с данной проблемой нужно сделать две ошибки: во#первых, использовать в теле метода и
    acctNum, и acctNo, ну, а во#вторых, объявить в методе обе эти переменные. Такую ошибку допустить сложнее, что практически устраняет про#
    блему похожих имен переменных. По сути языки, требующие явного объявления переменных, заставляют более внимательно использовать данные, что является одним из важнейших достоинств таких языков. А если язык поддерживает неяв#
    ные объявления? Несколько советов я привел ниже.
    Отключите неявные объявления Некоторые компиляторы позволяют запре#
    тить неявные объявления. Например, в Visual Basic для этого служит директива
    Option Explicit On, которая заставляет объявлять все используемые переменные.
    Объявляйте все переменные Печатая имя новой переменной, объявите ее, даже если компилятор этого не требует. Пусть не от всех, но от некоторых ошибок это вас избавит.
    Используйте конвенции именования Чтобы не исполь#
    зовать две переменные там, где предполагается одна, задайте конвенцию употребления популярных суффиксов в именах переменных. Скажем, конвенция может требовать примене#
    ния директивы
    Option Explicit On и суффикса No.
    Проверяйте имена переменных Просматривайте список перекрестных ссы#
    лок, сгенерированный компилятором или утилитой. Многие компиляторы состав#
    ляют список всех переменных метода, что, например, позволяет узнать о неумыш#
    ленном применении двух переменных с похожими именами. Кроме того, компи#
    ляторы могут указывать на объявленные, но неиспользованные переменные.
    10.3. Принципы инициализации переменных
    Неверная инициализация данных — один из самых плодородных источ#
    ников ошибок в программировании. Эффективные способы предотвра#
    щения проблем с инициализацией могут значительно ускорить отладку.
    При неверной инициализации проблемы объясняются тем, что переменная име#
    ет не то первоначальное значение, которое вы ожидаете. Это может случиться по одной из следующих причин.
    
    Переменной не было присвоено значения. Она имеет то случайное значение, которое находилось в соответству#
    ющих ячейках памяти при запуске программы.
    
    Значение переменной устарело. Когда#то переменной было присвоено значение, но оно утратило свою акту#
    альность.
    
    Одним частям переменной были присвоены значения, а другим нет.
    Последняя причина имеет несколько вариаций. Вы можете инициализировать несколько членов объекта, но не все. Вы можете забыть выделить память и ини#
    циализировать «переменную», на которую указывает неинициализированный ука#
    затель. При этом на самом деле вы занесете некоторое значение в случайный блок памяти. Им может оказаться область памяти, содержащая данные. Им может ока#
    Перекрестная ссылка О стандар- тизации сокращений имен см.
    подраздел «Общие советы по сокращению имен» раздела 11.6.
    Перекрестная ссылка О тести- ровании, основанном на шабло- нах инициализации данных и их использования, см. подраздел
    «Тестирование, основанное на потоках данных» раздела 22.3.

    234
    ЧАСТЬ III Переменные заться область памяти, содержащая код. В этом блоке может находиться фрагмент
    ОС. Проблема с указателями может проявляться совершенно неожиданным обра#
    зом, изменяющимся от случая к случаю, поэтому найти такие ошибки сложнее,
    чем любые другие.
    Ниже описаны способы предотвращения проблем, связанных с инициализацией.
    Инициализируйте каждую переменную при ее объявлении Инициализация переменных при их объявлении — простая методика защитного программиро#
    вания и хорошая страховка от ошибок инициализации. Так, следующий код по#
    зволяет гарантировать, что инициализация массива
    studentGrades будет выполняться при каждом вызове метода, содержащего массив:
    Пример инициализации массива при его объявлении (C++)
    float studentGrades[ MAX_STUDENTS ] = { 0.0 };
    Инициализируйте каждую переменную там, где она
    используется в первый раз Visual Basic и некоторые другие языки не позволяют инициализировать переменные при их объявлении. В результате код может принимать вид,
    при котором сначала выполняется объявление нескольких переменных, а потом эти переменные инициализируются — и то и другое про#
    исходит вдали от места фактического использования переменных в первый раз:
    Пример плохой инициализации
    переменных (Visual Basic)
    объявление всех переменных
    Dim accountIndex As Integer
    Dim total As Double
    Dim done As Boolean
    ’ инициализация всех переменных accountIndex = 0
    total = 0.0
    done = False
    ’ использование переменной accountIndex
    ’ использование переменной total
    ’ использование переменной done
    While Not done
    Лучше инициализировать каждую переменную как можно ближе к месту первого обращения к ней:
    Перекрестная ссылка Проверка входных параметров является еще одной формой защитного программирования (см. главу 8).

    1   ...   27   28   29   30   31   32   33   34   ...   106


    написать администратору сайта