Основы объектно-ориентированного программирования
Шрифт:
Важность этого критерия следует из его влияния на процесс сопровождения программного продукта. Почти все действия по сопровождению программы, как неизбежные, так и не столь неизбежные, связаны с глубоким пониманием ее элементов. Метод едва ли может называться модульным, если тот, кто читает программный текст, не в состоянии понять его смысл.
Рис. 3.4. Понятность
Этот критерий, подобно четырем остальным, применим к модулям при описании системы на любом уровне: анализа, проектирования, реализации.
[x]. Контрпример: последовательные зависимости. Предположим, что некоторые модули спроектированы таким образом, что они будут правильно функционировать лишь при их запуске в определенном заранее предписанном порядке. Например, B может работать надлежащим образом лишь при запуске его после A и перед C, возможно потому, что эти модули предназначены для использования в "конвейере" Unix, упоминавшемся ранее: A | B | C. В таком случае, по-видимому, трудно понять как работает B, не понимая работу A и C.
В последующих лекциях критерий модульной понятности поможет при рассмотрении двух важных вопросов: как документировать многократно используемые компоненты и как их индексировать, чтобы разработчики программного продукта могли без труда обращаться к ним путем соответствующего запроса. В соответствии с этим критерием информация о компоненте, полезная для документирования или поиска, должна, насколько это возможно, содержаться в тексте самого компонента, тогда средства документирования, индексации или поиска смогут обработать этот компонент и получить требуемую информацию.
Наличие нужной информации в каждом компоненте предпочтительнее хранения ее где-либо в другом месте, например в базе данных для хранения информации о компонентах.
Модульная Непрерывность
Метод удовлетворяет критерию Модульной Непрерывности, если незначительное изменение спецификаций разработанной системы приведет к изменению одного или небольшого числа модулей.
Этот критерий непосредственно связан с критерием расширяемости. Как подчеркивалось в предыдущей лекции, внесение изменений является неотъемлемой частью процесса разработки программного продукта. Соответствующие требования к программе будут неминуемо изменяться в ходе разработки. Непрерывность означает, что небольшие изменения будут воздействовать только на отдельные модули в структуре системы, а не на всю систему.
Термин "непрерывность" предлагается по аналогии с понятием непрерывной функции в математическом анализе. Математическая функция является непрерывной, если (неформально) малое изменение аргумента приводит к пропорционально малому изменению результата. В нашем случае роль функции играет метод конструирования программного продукта, который может рассматриваться как механизм, получающий на входе спецификации и возвращающий в качестве результата систему, удовлетворяющую заданным требованиям:
Рис. 3.5. Непрерывность
Этот математический термин введен здесь лишь по аналогии, поскольку не существует формального понятия размера спецификации и программы. Можно было бы ввести приемлемую меру для определения "небольших" или "больших" изменений программы, но дать подобное определение для спецификаций к программе это уже настоящая проблема. Однако если не претендовать на строгость, то такое интуитивно понятное определение будет соответствовать необходимому требованию к любому модульному методу.
[x]. Пример 1:именованные константы 3.2) . Разумный стиль не допускает в программе констант, заданных литералами. Вместо этого следует пользоваться именованными константами, значения которых даются в их определениях (constant в языках Pascal или Ada, макрокоманды препроцессоров в языке C, PARAMETER в языке Fortran 77, атрибуты констант в обозначениях этого курса). Если значение изменяется, то следует лишь внести единственное изменение в определение константы. Это простое, но важное правило является разумной мерой обеспечения непрерывности, потому что значения констант, несмотря на их название, довольно часто могут изменяться.
именованные константыименованные константы 3.2
[x]. Пример 2: принцип Унифицированного Доступа. Еще одно правило требует единой нотации при вызове свойств объекта независимо от того, представляют они обычные или вычислимые поля данных.
[x]. Контрпример 1: использование физического представления информации. Метод, в котором разрабатываемые программы согласуются с физической реализацией данных, будет приводить к конструкциям, весьма чувствительным к незначительным изменениям окружения.
[x]. Контрпример 2: статические массивы. Такие языки, как Fortran или стандартный Pascal, в которых не допускаются динамические массивы, границы которых становятся известными лишь во время выполнения программы, существенно усложняют развитие системы.
Модульная Защищенность
Метод удовлетворяет критерию Модульной Защищенности, если он приводит к архитектуре системы, в которой аварийная ситуация, возникшая во время выполнения модуля, ограничится только этим модулем, или, в худшем случае, распространится лишь на несколько соседних модулей.
Вопрос об отказах и ошибках является основным в программной инженерии. Сейчас речь идет об ошибках периода исполнения программы, связанных с аппаратными прерываниями, ошибочными входными данными или исчерпанием необходимых ресурсов (например, из-за недостаточного объема памяти). Критерий защищенности направлен не на предотвращение или исправление ошибок, а на проблему, непосредственно связанную с модульностью - распространением ошибок в модульной системе.
Рис. 3.6. Нарушение защищенности
[x]. Пример: проверка достоверности входных данных в источнике. Метод, требующий от каждого модуля, вводящего данные, проверку их достоверности, пригоден для реализации модульной защищенности. 3.3)
[x]. Контрпример: недисциплинированные (undisciplined) исключения. (Об обработке исключений см. лекцию 12) Такие языки как PL/I, CLU, Ada, C++ и Java поддерживают понятие исключения (exception). Исключение это ситуация, при которой программа не может нормально выполняться. Исключение "возбуждается" ("raised") некоторой командой модуля, и в результате операционной системе посылается специальный сигнал. Обработчик исключения (exception handler) может находиться в одном или нескольких модулях, расположенных в, возможно, удаленной части системы. Детали этого механизма отличаются в разных языках программирования; Ada или CLU являются более строгими в этом отношении, чем PL/I. Такие средства контроля ошибок позволяют отделить алгоритмы для обычных случаев от алгоритмов обработки ошибок. Но ими следует пользоваться осторожно, чтобы не нарушить модульную защищенность. В лекции 12, посвященной исключениям, рассматривается проектирование дисциплинированного (disciplined) механизма исключений, удовлетворяющего критерию защищенности.
Метод, требующий от каждого модуля, вводящего данные, проверку их достоверности, пригоден для реализации модульной защищенности.Метод, требующий от каждого модуля, вводящего данные, проверку их достоверности, пригоден для реализации модульной защищенности. 3.3
Пять правил
Из рассмотренных критериев следуют пять правил, которые должны соблюдаться, чтобы обеспечить модульность:
[x]. Прямое отображение (Direct Mapping).
[x]. Минимум интерфейсов (Few Interfaces).
[x]. Слабая связность интерфейсов (Small interfaces - weak coupling).
[x]. Явные интерфейсы (Explicit Interfaces).
[x]. Скрытие информации (инкапсуляция) (Information Hiding).