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

  • Процесс программирования с псевдокодом Содержание

  • ЧАСТЬ II

  • Рис. 91.

  • Создание общей структуры класса

  • Конструирование всех методов класса

  • Оценка и тестирование всего класса

  • ГЛАВА 9

  • 9.2. Псевдокод для профи

  • Пример плохого псевдокода

  • Пример хорошего псевдокода

  • Дополнительные сведения

  • 9.3. Конструирование методов с использованием ППП

  • Проверка предварительных условий

  • Определите задачу, решаемую методом

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

  • Решите, как тестировать метод

  • Исследуйте функциональность, предоставляемую стандартными биб

  • Продумайте обработку ошибок

  • Думайте об эффективности

  • Исследуйте алгоритмы и типы данных

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


    Скачать 5.88 Mb.
    НазваниеРуководство по стилю программирования и конструированию по
    АнкорСовершенный код
    Дата31.03.2023
    Размер5.88 Mb.
    Формат файлаpdf
    Имя файлаСовершенный код. Мастер-класс. Стив Макконнелл.pdf
    ТипРуководство
    #1028502
    страница29 из 106
    1   ...   25   26   27   28   29   30   31   32   ...   106
    ГЛАВА 9 Процесс программирования с псевдокодом
    209
    Г Л А В А 9
    Процесс программирования
    с псевдокодом
    Содержание
    
    9.1. Этапы создания классов и методов
    
    9.2. Псевдокод для профи
    
    9.3. Конструирование процедур с использованием ППП
    
    9.4. Альтернативы ППП
    Связанные темы
    
    Создание высококачественных классов: глава 6
    
    Характеристики высококачественных методов: глава 7
    
    Проектирование при конструировании: глава 5
    
    Стиль комментирования: глава 32
    Всю эту книгу можно рассматривать как подробное описание процесса програм#
    мирования, в результате которого создаются классы и методы, и в данной главе этапы этого процесса рассматриваются во всех деталях. Здесь описывается «про#
    граммирование в малом» — конкретные шаги построения отдельных классов и составляющих их методов, шаги, неизбежные в проекте любого размера. В этой главе также рассмотрен процесс программирования с псевдокодом (ППП, Pseu#
    docode Programming Process), уменьшающий объем работы по проектированию и документированию и улучшающий качество и первого, и второго.
    Если вы опытный программист, можете пропустить эту главу, но взгляните на обзор этапов и просмотрите советы по конструированию методов с помощью ППП в разделе 9.3. Некоторые программисты применяют описываемый процесс на пол#
    ную, поскольку он приносит большую выгоду.
    ППП — это не единственная процедура создания классов и методов. В разделе 9.4
    описаны наиболее популярные альтернативные подходы, включая разработку с изначальными тестами и проектирование по контракту.
    http://cc2e.com/0936

    210
    ЧАСТЬ II Высококачественный код
    9.1. Этапы создания классов и методов
    К конструированию классов можно подходить по#разному, но обычно это итера#
    тивный процесс создания общей структуры класса, создание списка его методов,
    их конструирование и проверка класса как единого целого. Создание класса мо#
    жет быть запутанным процессом (рис. 9#1), поскольку проектирование как тако#
    вое — тоже процесс запутанный (причины описаны в разделе 5.1).
    Рис. 9'1. Детали конструирования классов могут различаться,
    но обычно порядок действий такой
    Этапы создания класса
    Ниже перечислены основные этапы создания класса.
    Создание общей структуры класса Проектирование класса связано с мно#
    жеством отдельных вопросов. Определите функции класса, «секреты», скрытые в нем и точный уровень абстракции, предоставляемый интерфейсом класса. Опре#
    делите, наследуется ли класс от другого класса и могут ли другие классы наследо#
    ваться от него. Определите основные открытые методы класса и спроектируйте все нетривиальные структуры данных, используемые им. Пройдитесь по всем этим пунктам столько раз, сколько необходимо для создания четкой структуры класса.
    Эти и многие другие вопросы подробно обсуждаются в главе 6.
    Конструирование всех методов класса Определив на первом этапе основ#
    ные функции класса, переходите к конструированию каждого отдельного мето#
    да. При конструировании отдельных методов обычно выясняется потребность в дополнительных методах (как более низкого, так и более высокого уровня), и вопросы, возникающие при их создании, приводят к необходимости пересмотра общей структуры класса.
    Оценка и тестирование всего класса Обычно каждый метод тестируется при его создании. После того как класс в целом становится работоспособным, его нужно пересмотреть и протестировать как единое целое для выявления тех проблем,
    которые невозможно определить на уровне отдельных методов.

    ГЛАВА 9 Процесс программирования с псевдокодом
    211
    Этапы построения метода
    Многие метода класса, такие как аксессоры или интерфейсы к другим классам, могут быть простыми и понятными для реализации. Реализация других будет сложнее,
    и для их создания требуется систематический подход. Основные действия по со#
    зданию метода — проектирование, проверка структуры, кодирование и проверка кода — обычно выполняются в такой последовательности (рис. 9#2):
    Рис. 9'2. Основные действия по созданию метода
    Специалисты разработали множество подходов к созданию методов, но мой лю#
    бимый — процесс программирования с псевдокодом — описан в следующем раз#
    деле.
    9.2. Псевдокод для профи
    Псевдокодом называют неформальную нотацию на естественном языке, описы#
    вающую работу алгоритма, метода, класса или программы. «Процесс программи#
    рования с псевдокодом» относится к конкретной методике применения псевдо#
    кода для эффективного создания кода методов.
    Поскольку псевдокод напоминает естественный язык, разумно предположить, что любая перефразировка ваших мыслей, выполненная на нем, будет иметь одина#
    ковый эффект. На практике же вы обнаружите, что некоторые стили псевдокода предпочтительней других.
    
    Применяйте формулировки, в точности описывающие отдельные действия.
    
    Избегайте синтаксических элементов языков программирования. Псевдокод позволяет проектировать на несколько более высоком уровне, чем код. При#
    меняя конструкции языка программирования, вы мыслите на более низком уровне и теряете преимущества проектирования на высоком уровне, загружая себя ненужными синтаксическими ограничениями.

    212
    ЧАСТЬ II Высококачественный код
    
    Пишите псевдокод на уровне намерений. Описывайте назначение подхода, а не то, как этот подход нужно реали#
    зовать на выбранном языке программирования.
    
    Пишите псевдокод на достаточно низком уровне, так что#
    бы код из него генерировался практически автоматически.
    Если псевдокод написан на слишком высоком уровне, могут возникнуть про#
    блемы кодирования. Детализируйте псевдокод до тех пор, пока вам не пока#
    жется, что проще было бы написать код.
    1
    Написав псевдокод, вы окружаете его кодом, а псевдокод превращаете в коммен#
    тарии программы. Если вы руководствуетесь перечисленными правилами созда#
    ния псевдокода, комментарии в вашей программе будут полными и ясными.
    Вот пример псевдокода, в котором нарушены практически все перечисленные правила:
    Пример плохого псевдокода
    увеличить номер ресурса на 1
    выделить структуру dlg посредством malloc если malloc() возвращает NULL вернуть 1
    вызвать OSrsrc_init для инициализации ресурса
    *hRsrcPtr = номер ресурса вернуть 0
    Какие намерения описывает этот блок псевдокода? Трудно сказать, поскольку написан он плохо. Этот так называемый псевдокод плох потому, что включает конкретику целевого языка программирования:
    *hRsrcPtr (описание указателя,
    специфичное для языка C) и
    malloc() (функция C). Этот блок псевдокода показы#
    вает, как будет написан код, а не описывает его назначение. Он вдается в излиш#
    ние подробности: вернет ли процедура
    1 или 0. Если посмотреть, можно ли пре#
    вратить этот псевдокод в нормальные комментарии, видно, что толку от него мало.
    А вот описание тех же действий на гораздо лучшем псевдокоде:
    Пример хорошего псевдокода
    Отслеживать текущее число используемых ресурсов
    Если другой ресурс доступен
    Выделить структуру для диалогового окна
    Если структура для диалогового окна может быть выделена
    Учесть, что используется еще один ресурс
    Инициализировать ресурс
    Хранить номер ресурса в вызывающей программе
    Конец «если»
    Конец «если»
    Вернуть true, если новый ресурс был создан; иначе вернуть false
    Перекрестная ссылка Об уров- нях комментирования см. под- раздел «Виды комментариев»
    раздела 32.4.
    1
    К сожалению, эти советы хорошо применимы лишь для псевдокода на английском языке или для случаев использования экзотических языков программирования с конструкциями, осно#
    ванными на естественном языке, отличном от английского. —
    Прим. перев.

    ГЛАВА 9 Процесс программирования с псевдокодом
    213
    Этот псевдокод лучше предыдущего, так как полностью написан на естественном языке и не использует специфических конструкций целевого языка программи#
    рования. В первом примере псевдокод подлежал реализации только на C. Во вто#
    ром же псевдокод не накладывает ограничений на используемый язык. Второй блок также написан на уровне описания намерений. О чем речь во втором блоке? На#
    верное, это легче понять, чем в первом блоке.
    Хотя второй блок написан на понятном естественном языке, он достаточно то#
    чен и подробен, чтобы быть основой программы. Когда предложения этого псев#
    докода будут преобразованы в комментарии, они станут хорошим пояснением на#
    значения кода.
    Вот выгоды, которые вы получите, применяя такой стиль псевдокода.
    
    Псевдокод упрощает пересмотр конструкции — вам не потребуется вникать в исходный код.
    
    Псевдокод поддерживает идею итеративного усовершенствования. Вы начинаете с высокоуровневой конструкции, уточняете ее до псевдокода, который в свою очередь преобразуете в исходный код. Такое последовательное усовершенство#
    вание, осуществляемое шаг за шагом, позволяет проверять свои проектные решения по мере перехода на более низкие уровни. В результате вы обнару#
    живаете высокоуровневые ошибки на самом верхнем уровне, среднеуровне#
    вые — на среднем, а низкоуровневые — на самом нижнем, прежде чем они создадут проблемы.
    
    Псевдокод упрощает внесение изменений. Что проще:
    исправить линию на чертеже или снести стену и сдви#
    нуть ее на метр в сторону? В программировании эффект не столь драматичен в плане физических усилий, но идея та же: несколько строк псевдокода легче исправить, чем страницу кода. Одна из основ успеха проекта — отловить ошибку на «наименее значимой стадии», когда для ее исправления требуется минимум усилий. Поиск ошибки на стадии псевдокода требует гораздо мень#
    ше затрат, чем после полного кодирования, тестирования и отладки, так что есть экономический стимул обнаружить ошибку как можно раньше.
    
    Псевдокод упрощает комментирование программ. В типичной ситуации вы сначала пишете код, а затем добавляете комментарии. В ППП предложения псевдокода становятся комментариями, так что на самом деле их проще оста#
    вить, чем удалить.
    
    Псевдокод сопровождать проще, чем другие виды проектной документации. При других подходах проектная документация отделена от кода, и внесение в нее изменений порождает несоответствие. В ППП предложения псевдокода стано#
    вятся комментариями программы. Внося изменения в комментарии, вы, таким образом, поддерживаете в корректном состоянии проектную документацию.
    Псевдокод как инструмент проектирования трудно переоценить. Иссле#
    дования показали, что программисты предпочитают псевдокод за его воз#
    можности упрощать создание программных конструкций, помощь в определении некорректных проектных решений, простоту документирования и внесения изменений (Ramsey, Atwood, and Van Doren, 1983). Псевдокод — не един#
    Дополнительные сведения О пре- имуществах внесения изменения на наименее значимых стадиях см. книгу Энди Гроува «High Out- put Management» (Grove, 1983).

    214
    ЧАСТЬ II Высококачественный код ственный инструмент детального проектирования, но наряду с ППП — полезная вещь в инструментарии программиста. Попробуйте его в деле. В следующем раз#
    деле я расскажу как.
    9.3. Конструирование методов
    с использованием ППП
    В этом разделе описаны этапы конструирования методов, а именно:
    
    проектирование метода;
    
    кодирование метода;
    
    проверка кода;
    
    наведение глянца;
    
    повторение предыдущих шагов при необходимости.
    Проектирование метода
    Определив состав методов класса, приступайте к их проек#
    тированию. Допустим, вы хотите написать метод вывода сообщения об ошибке, основанного на коде ошибки, и на#
    звали этот метод
    ReportErrorMessage(). Вот неформальная спецификация
    ReportErrorMessage():
    ReportErrorMessage() принимает в качестве входного параметра код ошибки и выводит сообщение об ошибке, соответствующее этому коду. Он отвечает за обработку недопустимых кодов. Если программа интерактивная,
    ReportError%
    Message() выводит сообщение пользователю. Если она работает в режиме ко#
    мандной строки,
    ReportErrorMessage() заносит сообщение в файл. После выво#
    да сообщения
    ReportErrorMessage() возвращает значение статуса, указывающее,
    успешно ли он завершился.
    Этот метод используется в качестве примера во всей главе, а в оставшейся части этого раздела описывается его проектирование.
    Проверка предварительных условий Прежде чем что#
    либо делать с самой процедурой, убедитесь, что функции метода четко определены и соответствуют общим проект#
    ным решениям.
    Определите задачу, решаемую методом Сформулируйте задачу, решаемую методом настолько детально, чтобы можно было переходить созданию метода. Если проект высокого уровня достаточно подробен, эта работа уже сделана. Проект верхнего уровня должен содержать по крайней мере:
    
    информацию, скрываемую методом;
    
    входные данные;
    
    выходные данные;
    
    предусловия, которые гарантированно должны соблюдать#
    ся до вызова метода (входные значения находятся в задан#
    ном диапазоне, потоки инициализированы, файлы открыты или закрыты, буферы заполнены или очищены и т. д.);
    Перекрестная ссылка О других аспектах проектирования см.
    главы с 5 по 8.
    Перекрестная ссылка О провер- ке предварительных условий см.
    главы 3 и 4.
    Перекрестная ссылка О пред- и постусловиях см. раздел 8.2.

    ГЛАВА 9 Процесс программирования с псевдокодом
    215
    
    постусловия, которые гарантированно должны соблюдаться, прежде чем ме#
    тод вернет управление вызывающей программе (выходные значения находят#
    ся в заданном диапазоне, потоки инициализированы, файлы открыты или за#
    крыты, буферы заполнены или очищены и т. д.).
    Вот как это выглядит для метода
    ReportErrorMessage():
    
    метод скрывает текст сообщения и текущий метод обработки (интерактивный или командной строки);
    
    выполнение каких#либо предусловий не требуется;
    
    входными данными является код ошибки;
    
    выходные данные двух видов: сообщение об ошибке и статус, возвращаемый
    ReportErrorMessage() вызывающей программе;
    
    возвращаемый статус должен принимать одно из двух значений:
    Success или
    Failure.
    Название метода Вопрос именования метода кажется тривиальным, но хорошее название — признак высокого стиля программирования и дело это непростое. Вообще ме#
    тод должен иметь понятное, недвусмысленное имя. Затруднения в выборе имени метода могут свидетельствовать о том, что его назначение не совсем понятно. Не#
    ясное, невыразительное имя метода сродни предвыборным обещаниям политиков.
    Вроде бы о чем#то оно говорит, но если задуматься — непонятно о чем. Если мож#
    но дать методу более ясное имя, сделайте это. Если невыразительное имя — результат неясных проектных решений, вернитесь к ним и измените их.
    В нашем примере
    ReportErrorMessage() — вполне недвусмысленное имя. Хорошее имя.
    Решите, как тестировать метод В процессе написа#
    ния метода думайте о том, как вы будете его тестировать. Это принесет пользу вам при блочном тестировании и тести#
    ровщикам, проводящим независимое тестирование.
    В нашем примере входные данные просты, так что можно планировать тестирование
    ReportErrorMessage() со всеми допустимыми кодами ошибок и различными неверными кодами.
    Исследуйте функциональность, предоставляемую стандартными биб'
    лиотеками Основная возможность улучшить качество и производительность своего кода — повторно использовать имеющийся хороший код. Если метод ка#
    жется вам слишком сложным и у вас возникают проблемы с его проектировани#
    ем, спросите себя, не реализована ли часть его функциональности в библиотеках языка, платформы или средства разработки, которые вы применяете. Нет ли нуж#
    ного кода в стандартных библиотеках вашей компании? Множество алгоритмов уже реализовано, протестировано, обсуждено в профессиональной литературе,
    пересмотрено и усовершенствовано. Не тратьте время на реализацию готового алгоритма, по которому написана кандидатская диссертация.
    Продумайте обработку ошибок Подумайте обо всем плохом, что может слу#
    читься с вашим методом. Подумайте о плохих входных данных, недопустимых значениях, возвращаемых другими методами, и т. д.
    Перекрестная ссылка Об имено- вании методов см. раздел 7.3.
    Дополнительные сведения О
    различных подходах к констру- ированию, ориентированных на предварительное написание те- стов см. книгу «Test-Driven De- velopment: By Example» (Beck,
    2003).

    216
    ЧАСТЬ II Высококачественный код
    Методы могут обрабатывать ошибки разными способами, и вам нужно четко опре#
    делиться с одним из них. Если стратегию обработки ошибок определяет архитек#
    тура программы, вы можете просто следовать этой стратегии. В других случаях вам следует решить, какой подход будет оптимален в данном конкретном случае.
    Думайте об эффективности В зависимости от ситуации вы можете подхо#
    дить к эффективности одним из двух способов. В первом случае — в подавляю#
    щем большинстве систем — эффективность некритична. При этом убедитесь, что интерфейс метода достаточно абстрагирован, а код читабелен и при необходи#
    мости вы сможете его легко усовершенствовать. При хорошей инкапсуляции вы сможете заменить медленные, ресурсоемкие конструкции языка высокого уров#
    ня более эффективным алгоритмом или реализацией на быстром, компактном язы#
    ке низкого уровня, не затронув при этом другие методы.
    Во втором случае — в незначительном числе систем — про#
    изводительность критична. Проблемы производительности могут быть связаны с недостатком соединений с базой дан#
    ных, ограниченной памятью, малым количеством доступных дескрипторов и дру#
    гими ресурсами. Архитектура должна указывать, сколько ресурсов каждому мето#
    ду (или классу) может быть предоставлено и как быстро он должен выполнять свои операции.
    Как правило, не стоит тратить много усилий на оптимизацию отдельных мето#
    дов. Эффективность в основном определяется конструкцией высокого уровня.
    Обычно микрооптимизация выполняется, только когда закончена вся программа и выясняется, что высокоуровневая конструкция исчерпала свои возможности обеспечить нужную производительность. Не теряйте время на вылизывание от#
    дельных методов, пока не выяснится, что это необходимо.
    Исследуйте алгоритмы и типы данных Если доступные стандартные биб#
    лиотеки не предоставляют нужной функциональности, имеет смысл исследовать литературу с описанием алгоритмов. Если вы нашли подходящий готовый алго#
    ритм, корректно адаптируйте его к применяемому вами языку программирования.
    Пишите псевдокод У вас не будет сложностей, если вы прошли все предыду#
    щие этапы, основное назначение которых в том, чтобы у вас сложилось четкое понимание того, что нужно писать.
    Закончив предыдущие этапы, можно приступать к написа#
    нию высокоуровневого псевдокода. Запускайте редактор кода или интегрированную среду разработки и пишите псевдокод, который станет основой исходного текста про#
    граммы.
    Начните с основных моментов, а затем детализируйте их.
    Самая главная часть метода — заголовок#комментарий, описывающий действия метода, так что начните с краткой формулировки назначения метода. Написание этой формулировки поможет вам прояснить ваше понимание метода. Если вы испытываете затруднения при написании этого обобщенного комментария, вам,
    видимо, следует лучше разобраться с ролью этого метода. Вот пример краткого заголовка#комментария метода:
    Перекрестная ссылка Об эф- фективности см. главы 25 и 26.
    Перекрестная ссылка Это обсуж- дение предполагает, что при создании псевдокода метода применялись правильные спосо- бы проектирования (см. главу 5).

    1   ...   25   26   27   28   29   30   31   32   ...   106


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