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

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

  • Пользовательский интерфейс

  • Взаимодействие с другими системами

  • ЧАСТЬ I

  • Возможность реализации архитектуры

  • Избыточная функциональность

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


    Скачать 5.88 Mb.
    НазваниеРуководство по стилю программирования и конструированию по
    АнкорСовершенный код
    Дата31.03.2023
    Размер5.88 Mb.
    Формат файлаpdf
    Имя файлаСовершенный код. Мастер-класс. Стив Макконнелл.pdf
    ТипРуководство
    #1028502
    страница8 из 106
    1   ...   4   5   6   7   8   9   10   11   ...   106
    ГЛАВА 3 Семь раз отмерь, один раз отрежь: предварительные условия
    43
    архитектура обосновывает организацию системы и показывает, что роль каждо#
    го класса была тщательно рассмотрена. В одном обзоре методик проектирования было обнаружено, что обоснование проекта программы не менее важно для ее сопровождения, чем сам проект (Rombach, 1990).
    Архитектура должна определять основные компоненты программы. В зависимости от размера программы ее ком#
    понентами могут быть отдельные классы или подсистемы,
    состоящие из нескольких классов. Каждый компонент яв#
    ляется классом или набором классов/методов, которые в совокупности реализуют высокоуровневые функции про#
    граммы, такие как взаимодействие с пользователем, отображение Web#страниц,
    интерпретация команд, инкапсуляция бизнес#правил или доступ к данным. За каждую функцию приложения, указанную в требованиях, должен отвечать хотя бы один компонент. Если функцию реализуют несколько компонентов, они дол#
    жны сотрудничать, а не конфликтовать.
    Архитектура должна четко определять ответственность каж#
    дого компонента. Компонент должен иметь одну область ответственности и как можно меньше знать об областях ответственности других компонентов. Сведя к минимуму объем сведений, известных компонентам о других компо#
    нентах, вы сможете локализовать информацию о проекте приложения в отдельных компонентах.
    Архитектура должна ясно определять правила коммуника#
    ции для каждого компонента. Она должна описывать, какие другие компоненты данный компонент может использовать непосредственно, какие косвенно, а ка#
    кие вообще не должен использовать.
    Основные классы
    Архитектура должна определять основные классы приложе#
    ния, их области ответственности и механизмы взаимодей#
    ствия с другими классами. Она должна описывать иерархии классов, а также изменения состояний и время существова#
    ния объектов. Если система достаточно велика, архитектура должна описывать орга#
    низацию классов в подсистемы.
    Архитектура должна описывать другие рассматривавшиеся варианты организации классов и обосновывать итоговый вариант. Не все классы системы нужно описы#
    вать в спецификации архитектуры. Ориентируйтесь на правило 80/20: описывайте
    20% классов, которыми на 80% определяется поведение системы (Jacobsen, Booch,
    and Rumbaugh, 1999; Kruchten, 2000).
    Организация данных
    Архитектура должна описывать основные виды формата файлов и таблиц. Она должна описывать рассмотренные аль#
    тернативы и обосновывать итоговые варианты. Если при#
    ложение использует список идентификаторов клиентов и разработчики архитектуры решили реализовать его при помощи списка с после#
    Перекрестная ссылка Об ис- пользуемых при проектирова- нии компонентах разных уров- ней см. подраздел «Уровни про- ектирования» раздела 5.2.
    Перекрестная ссылка Миними- зация объема сведений, извес- тных компонентам друг о дру- ге, — главный аспект сокрытия информации. Подробности см.
    в подразделе «Скрывайте сек- реты (к вопросу о сокрытии информации)» раздела 5.3.
    Перекрестная ссылка О проек- тировании классов см. главу 6.
    Перекрестная ссылка Об ис- пользовании переменных см.
    главы 10–13.

    44
    ЧАСТЬ I Основы разработки ПО
    довательным доступом, в документации должно быть сказано, почему этот вид списка лучше, чем список с произвольным доступом, стек или хэш#таблица. Эта информация окажет вам неоценимую помощь во время конструирования и со#
    провождения программы, подсказав, чем руководствовались разработчики архи#
    тектуры. Без нее вы будете чувствовать себя зрителем, который смотрит иност#
    ранный фильм без субтитров.
    Прямой доступ к данным обычно следует предоставлять только одной подсисте#
    ме или классу; исключения возможны при использовании классов или методов доступа, обеспечивающих доступ к данным, контролируемым абстрактным обра#
    зом. Подробнее об этом см. подраздел «Скрывайте секреты (к вопросу о сокры#
    тии информации)» раздела 5.3.
    Архитектура должна определять высокоуровневую организацию и содержание всех используемых БД. Архитектура должна объяснять, почему одна БД предпочтитель#
    нее, чем несколько (или наоборот), почему БД предпочтительнее, чем однород#
    ные файлы, определять возможные типы взаимодействия приложения с другими программами, использующими те же данные, объяснять, как будут отображаться данные, и т. д.
    Бизнес-правила
    Архитектура, зависимая от специфических бизнес#правил, должна определять их и описывать их влияние на проект системы. Возьмем для примера бизнес#прави#
    ло, согласно которому информация о клиентах должна устаревать не более чем на 30 секунд. В данном случае в спецификации архитектуры должно быть указа#
    но, как это правило повлияло на выбор метода обеспечения актуальности данных и их синхронизации.
    Пользовательский интерфейс
    Пользовательский интерфейс (GUI) часто проектируется на этапе выработки тре#
    бований. Если это не так, его следует определить на этапе разработки архитекту#
    ры. Архитектура должна описывать главные элементы формата Web#страниц, GUI,
    интерфейс командной строки и т. д. Удобство GUI может в итоге определить по#
    пулярность или провал программы.
    Архитектура должна быть модульной, чтобы GUI можно было изменить, не зат#
    ронув бизнес#правил и модулей программы, отвечающих за вывод данных. Напри#
    мер, архитектура должна обеспечивать возможность сравнительно легкой заме#
    ны группы классов интерактивного интерфейса на группу классов интерфейса командной строки. Такая возможность весьма полезна; во многом это объясняет#
    ся тем, что интерфейс командной строки удобен для тестирования ПО на уровне блоков или подсистем.
    Проектирование GUI заслуживает отдельной книги, и мы его рассматривать не будем.
    Управление ресурсами
    Архитектура должна включать план управления ограниченными ресурсами, такими как соединения с БД, потоки и дескрипторы. При разработке драйверов, встро#
    енных систем и других приложений, которые будут работать в условиях ограни#
    http://cc2e.com/0393

    ГЛАВА 3 Семь раз отмерь, один раз отрежь: предварительные условия
    45
    ченной памяти, архитектура должна также определять способ управления памя#
    тью. Архитектура должна включать оценку ресурсов, используемых в номиналь#
    ном режиме и при экстремальной нагрузке. В простейшем случае эти оценки должны подтвердить, что предполагаемая среда использования приложения бу#
    дет располагать нужными ресурсами. В более сложной ситуации в приложении,
    возможно, придется реализовать более активное управление выделенными ему ресурсами. Если это так, архитектуру менеджера ресурсов нужно спроектировать не менее тщательно, чем любой другой компонент системы.
    Безопасность
    Архитектура должна определять подход к безопасности на уровне проекта приложения и на уровне кода. Если модель угроз до сих пор не разработана, это следует сделать при проектировании архитектуры. О безопасности нужно по#
    мнить и при разработке принципов кодирования, в том числе методик обработки буферов и ненадежных данных
    (данных, вводимых пользователями, файлов «cookie», кон#
    фигурационных данных и данных других внешних интер#
    фейсов), подходов к шифрованию, уровню подробности сообщений об ошибках, защите секретных данных, нахо#
    дящихся в памяти, и другим вопросам.
    Производительность
    В требованиях следует определить показатели производи#
    тельности. Если они связаны с использованием ресурсов,
    надо определить приоритеты для разных ресурсов, в том числе соотношение быстродействия, использования памя#
    ти и затрат.
    Архитектура должна включать оценки производительности и объяснять, почему разработчики архитектуры считают эти показатели дости#
    жимыми. Если они могут быть не достигнуты, это тоже должно быть отражено в архитектуре. Если для достижения некоторых показателей требуются специфи#
    ческие алгоритмы или типы данных, также укажите это в спецификации архитек#
    туры. Кроме того, в архитектуре можно указать объем пространства и время, вы#
    деляемые каждому классу или объекту.
    Масштабируемость
    Масштабируемостью называют возможность системы адаптироваться к росту тре#
    бований. Архитектура должна описывать, как система будет реагировать на рост числа пользователей, серверов, сетевых узлов, записей в БД, транзакций и т. д. Если развитие системы не предполагается и ее масштабируемость не играет роли, это должно быть явно указано в архитектуре.
    Взаимодействие с другими системами
    Если некоторые данные или ресурсы будут общими для разрабатываемой систе#
    мы и других программ или устройств, в архитектуре нужно указать, как это будет реализовано.
    http://cc2e.com/0330
    Дополнительные сведения Пре- красное обсуждение защиты ПО
    см. в книге «Writing Secure Code,
    2d Ed.» (Howard and LeBlanc 2003)
    и в январском номере журнала
    «IEEE Software» за 2002 год.
    Дополнительные сведения О про- ектировании высокопроизводи- тельных систем см. книгу Конни
    Смит «Performance Engineering of
    Software Systems» (Smith, 1990).

    46
    ЧАСТЬ I Основы разработки ПО
    Интернационализация/локализация
    «Интернационализацией» называют реализацию в программе поддержки региональ#
    ных стандартов. Вместо слова «internationalization» часто используется аббревиату#
    ра «I18n», составленная из первой и последней букв слова и числа букв между ними.
    «Локализацией» (известной как «L10n» по той же причине) называют перевод интер#
    фейса программы и реализацию в ней поддержки конкретного языка.
    Вопросы интернационализации заслуживают особого внимания при разработке архитектуры интерактивной системы. Большинство интерактивных систем вклю#
    чает десятки или сотни подсказок, индикаторов состояния, вспомогательных со#
    общений, сообщений об ошибках и т. д., поэтому нужно оценить объем ресурсов,
    используемых строками. Если разрабатывается коммерческая программа, архитек#
    тура должна показывать, что при ее создании были рассмотрены типичные вопро#
    сы, связанные со строками и наборами символов, такие как выбор набора симво#
    лов (ASCII, DBCS, EBCDIC, MBCS, Unicode, ISO 8859 и т. д.) и типа строк (строки C,
    строки Visual Basic и т. д.), а также способа изменения строк, который не требовал бы изменения кода, и метода перевода строк на иностранные языки, оказывающе#
    го минимальное влияние на код и GUI. Строки можно встроить в код, инкапсули#
    ровать в класс и использовать посредством интерфейса или сохранить в файле ресурсов. Архитектура должна объяснять, какой вариант выбран и почему.
    Ввод-вывод
    Ввод#вывод — еще одна область, на которую стоит обратить внимание при про#
    ектировании архитектуры. Архитектура должна определять схему чтения данных:
    упреждающее чтение, чтение с задержкой или по требованию. Кроме того, она должна описывать уровень, на котором будут определяться ошибки ввода#выво#
    да: на уровне полей, записей, потоков данных или файлов.
    Обработка ошибок
    Обработка ошибок — одна из самых сложных проблем современной ин#
    форматики, и к ней нельзя относиться с пренебрежением. По оценкам некоторых ученых код на целых 90% состоит из блоков обработки ис#
    ключительных ситуаций, ошибок и т. п., из чего следует, что только 10% кода от#
    вечают за номинальный режим работы программы (Shaw in Bentley, 1982). Раз уж на обработку ошибок приходится такая большая часть кода, стратегия их согла#
    сованной обработки должна быть выражена в архитектуре.
    Обработку ошибок часто рассматривают на уровне конвенции кодирования, если вообще рассматривают. Однако она оказывает влияние на всю систему, поэтому лучше всего рассматривать ее на уровне архитектуры. Вот некоторые вопросы, на которые нужно обратить внимание.
    
    Является ли обработка ошибок корректирующей или ориентированной на их простое обнаружение? В первом случае программа может попытаться восста#
    новиться от последствий ошибки. Во втором — может продолжить работу как ни в чем не бывало или завершиться. Как бы то ни было, она должна извес#
    тить пользователя об ошибке.

    ГЛАВА 3 Семь раз отмерь, один раз отрежь: предварительные условия
    47
    
    Является ли обнаружение ошибок активным или пассивным? Система может активно предвосхищать ошибки (например, проверяя корректность данных,
    введенных пользователем) или пассивно реагировать на них только в том случае,
    если избежать их не удалось (например, когда введенные пользователем дан#
    ные привели к численному переполнению). В обоих случаях сделанный вы#
    бор повлияет на дизайн GUI.
    
    Как программа поступает при обнаружении ошибки? Обнаружив ошибку, про#
    грамма может отбросить данные, вызвавшие ошибку, может отнестись к ошибке как положено и перейти в состояние обработки ошибки или может выполнить оставшиеся действия и уведомить пользователя о том, что (где#то) были обна#
    ружены ошибки.
    
    Каковы соглашения обработки сообщений об ошибках? Если в спецификации архитектуры не определена единственная согласованная стратегия, GUI пока#
    жется непонятной комбинацией разных интерфейсов, относящихся к разным частям программы. Чтобы избежать этого, при проектировании архитектуры нужно определить соглашения вывода сообщений об ошибках.
    
    Как обрабатываются исключения? Архитектура должна определять, когда код может генерировать исключения, где они будут перехватываться, как регист#
    рироваться в журнале, документироваться и т. д.
    
    На каком уровне программы обрабатываются ошибки?
    Вы можете обрабатывать их в точке обнаружения, пере#
    давать классу обработки ошибок или возвращать по цепи вызовов.
    
    Какова ответственность каждого класса за проверку по#
    лучаемых данных? Каждый класс отвечает за проверку собственных данных или есть группа классов, проверя#
    ющих данные для всей системы? Могут ли классы кон#
    кретного уровня полагать, что полученные ими данные корректны?
    
    Хотите ли вы использовать механизм обработки ошибок, встроенный в среду программирования, или создать собственный? Если в среде реализован кон#
    кретный подход к обработке ошибок, это не значит, что он лучше всего соот#
    ветствует вашим требованиям.
    Отказоустойчивость
    При разработке архитектуры системы следует указать ожидаемый уровень ее отка#
    зоустойчивости. Отказоустойчивостью называют совокупность свойств системы, по#
    вышающих ее надежность путем обнаружения ошибок, восстановления, если это возможно, и изоляции их плохих последствий, если восстановление невозможно.
    Например, вычисление системой квадратного корня можно сделать отказоустой#
    чивым несколькими способами.
    
    В случае неудачи система может вернуться в предыдущее состояние и попро#
    бовать вычислить корень еще раз. Если первый ответ неверен, она может вер#
    нуться в состояние, при котором все наверняка было правильно, и продолжить работу с этого момента.
    Перекрестная ссылка Еще один аспект стратегии обработки ошибок, который следует рас- смотреть на архитектурном уровне, — согласованный метод обработки недопустимых пара- метров. Примеры см. в главе 8.

    48
    ЧАСТЬ I Основы разработки ПО
    
    Система может включать вспомогательный код, выпол#
    няемый при обнаружении ошибки в основном коде. Так, если первый ответ кажется ошибочным, система может переклю#
    читься на альтернативный метод вычисления квадратного корня.
    
    Система может применять алгоритм голосования. Она может включать три класса, вычисляющих квадратный ко#
    рень разными способами. Каждый класс вычисляет квадрат#
    ный корень, после чего система сравнивает полученные результаты. В зависимости от реализованного типа отказоустойчивости сис#
    тема может использовать среднее, срединное или наиболее вероятное значе#
    ние из трех.
    
    Система может заменять ошибочное значение поддельным значением, кото#
    рое положительно скажется на работе оставшейся части системы.
    Другими подходами к отказоустойчивости являются перевод системы при обна#
    ружении ошибки в состояние частичной работоспособности или ограниченной фунциональности. Система может отключиться или автоматически перезапустить себя. Конечно, эти примеры упрощены. Отказоустойчивость — захватывающая и сложная область, но не она является темой этой книги.
    Возможность реализации архитектуры
    Разработчики могут сомневаться в том, способна ли система достигнуть заданных показателей производительности, работать при ограниченности ресурсов и бу#
    дет ли она адекватно поддержана средами реализации. Архитектура должна под#
    тверждать, что система технически осуществима. Если невозможность реализации какого#то компонента может сделать проект неработоспособным, в архитектуре должно быть отражено, как изучались эти вопросы: при помощи прототипов,
    исследований или иначе. Эти аспекты риска следует устранить до начала полно#
    масштабного конструирования.
    Избыточная функциональность
    Надежностью называют способность системы продолжать работу после обнару#
    жения ошибки. Частенько в спецификации архитектуры разработчики определя#
    ют более надежную систему, чем указано в требованиях. Одна из причин этого в том, что система, состоящая из многих частей, удовлетворяющих минимальным требованиям к надежности, в целом может оказаться менее надежной, чем нуж#
    но. В мире ПО цепь не так крепка, как слабейшее звено; она так слаба, как все слабые звенья, вместе взятые. В спецификации архитектуры должно быть явно указано,
    могут ли программисты реализовать в своих блоках программы избыточную фун#
    кциональность или они должны создать простейшую работоспособную систему.
    Определить отношение к реализации избыточной функциональности особенно важно потому, что многие программисты делают это автоматически, из чувства профессиональной гордости. Явно выразив ожидания в архитектуре, вы сможете избежать феномена, при котором некоторые классы исключительно надежны, а другие лишь отвечают требованиям.
    Дополнительные сведения Хо- рошее введение в вопросы от- казоустойчивости см. в июльс- ком номере журнала «IEEE Soft- ware» за 2001 год. Кроме того,
    в статьях этого номера есть ссылки на многие отличные книги и статьи, посвященные данной теме.

    1   ...   4   5   6   7   8   9   10   11   ...   106


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