Организация взаимодействия между устройствами сети является сложной задачей. Для решения сложных задач используется известный универсальный прием — декомпозиция, то есть разбиение одной сложной задачи на несколько более простых задач-модулей. Декомпозиция состоит в четком определении функций каждого модуля, а также порядка их взаимодействия (то есть межмодульных интерфейсов). При таком подходе каждый модуль можно рассматривать как «черный ящик», абстрагируясь от его внутренних механизмов и концентрируя внимание на способе взаимодействия этих модулей. В результате такого логического упрощения задачи появляется возможность независимого тестирования, разработки и модификации модулей. Так, любой из показанных на рис. 4.1 модулей может быть переписан заново. Пусть, например, это будет модуль Л, и если при этом разработчики сохранят без изменения межмодульные связи (в данном случае интерфейсы А-В и Л-С), то это не потребует никаких изменений в остальных модулях.
Рис. 4.1. Пример декомпозиции задачи |
Еще более эффективной концепцией, развивающей идею декомпозиции, является многоуровневый подход. После представления исходной задачи в виде множества модулей эти модули группируют и упорядочивают по уровням, образующим иерархию. В соответствии с принципом иерархии для каждого промежуточного уровня можно указать непосредственно примыкающие к нему соседние вышележащий и нижележащий уровни (рис. 4.2).
Уровень 3Уровень 2Уровень 1 | |
Рис. 4.2. Многоуровневый подход — создание иерархии задач |
С одной стороны, группа модулей, составляющих каждый уровень, для решения своих задач должна обращаться с запросами только к модулям соседнего нижележащего уровня. С другой стороны, результаты работы каждого из модулей, отнесенных к некоторому уровню, могут быть переданы только модулям соседнего вышележащего уровня. Такая иерархическая декомпозиция задачи предполагает четкое определение функций и интерфейсов не только отдельных модулей, но и каждого уровня.
Межуровневый интерфейс, называемый также интерфейсом услуг, определяет набор функций, которые нижележащий уровень предоставляет вышележащему (рис. 4.3). 1920
К уровню к+2 |
---|
К уровню к -1Рис. 4.3. Концепция многоуровневого взаимодействия |
2. Определение считываемой части файла.
Для решения этой задачи необходимо снизить степень абстракции файловой системы. Функции данного уровня оперируют файлом как совокупностью определенным образом связанных физических блоков диска.
3. Считывание данных с диска.
После определения номера физического блока файловая система обращается к системе ввода-вывода для выполнения операции чтения. На этом уровне уже фигурируют такие детали устройства файловой системы, как номера цилиндров, дорожек, секторов.
Среди функций, которые может запросить прикладная программа, обращаясь к верхнему уровню файловой системы, может быть, например, такая:
ПРОЧИТАТЬ гг ЛОГИЧЕСКУЮ запись файла diri/my/file.txt
Верхний уровень не может выполнить этот запрос «только своими силами», определив по символьному имени DIR1/MY/FILE.TXT физический адрес файла, он обращается с запросом к нижележащему уровню:
ПРОЧИТАТЬ 22 ЛОГИЧЕСКУЮ ЗАПИСЬ ИЗ ФАЙЛА,
ИМЕЮЩЕГО ФИЗИЧЕСКИЙ АДРЕС 174 И РАЗМЕР 235
В ответ на запрос второй уровень определяет, что файл с адресом 174 занимает на диске пять несмежных областей, а искомая запись находится в четвертой области в физическом блоке 345. После этого он обращается к драйверу с запросом о чтении требуемой логической записи.
В соответствии с этой упрощенной схемой взаимодействие уровней файловой системы было однонаправленным — сверху вниз. Однако реальная картина существенно сложнее. Действительно, чтобы определить характеристики файла, верхний уровень должен «раскрутить» его символьное имя, то есть последовательно прочитать всю цепочку каталогов, указанную в имени файла. А это значит, что для решения свой задачи он несколько раз обратится к нижележащему уровню, который, в свою очередь, несколько раз «попросит» драйвер считать данные каталогов с диска. И каждый раз результаты будут передаваться снизу вверх.
Задача организации взаимодействия компьютеров в сети тоже может быть представлена в виде иерархически организованного множества модулей. Например, модулям нижнего уровня можно поручить вопросы, связанные с надежной передачей информации между двумя соседними узлами, а модулям следующего, более высокого уровня — транспортировку сообщений в пределах всей сети. Очевидно, что последняя задача — организация связи двух любых, не обязательно соседних, узлов — является более общей и поэтому ее решение может быть получено путем многократных обращений к нижележащему уровню. Так, организация взаимодействия узлов А и В может быть сведена к поочередному взаимодействию пар промежуточных смежных узлов (рис. 4.4).