Связь модулей системы

Мы определили модульность как способ получения легко управляемого программного обеспечения. Суть заключается в том, что все изменения можно вносить в конкретные модули, то есть в процессе модификации можно сосредоточить внимание только на определенной части системы. В основе этого находится предположение, что изменение одного модуля никак не отразится на работе других модулей системы. Следовательно, основная цель при проектировании модульной системы — сделать модули максимально независимыми друг от друга. Однако при этом, чтобы модули составляли связную и логичную систему, между ними должны существовать связи. Они называются межмодульными связями (intermodule coupling). Следовательно, создать модули, максимально независимые друг от друга, значит минимизировать связи модулей системы.

Существует несколько видов межмодульных связей. Во-первых, связь по управлению (control coupling), когда один модуль системы передает управление другому модулю — это процесс передачи-возврата управления между процедурами программы. Во-вторых, связь модулей по данным (data coupling), когда модули совместно используют какие-либо данные.

Связь модулей по управлению в нашей системе заказа товаров через Интернет, построенной согласно принципам процедурного программирования, изображена на рис. 6.3. Связь модулей по данным изображается на структурной схеме с помощью дополнительных стрелок (рис. 6.5). На этой схеме показаны данные, которые передаются модулю при вызове, и данные, которые возвращаются вызывающему модулю после выполнения затребованной задачи. В частности, схема показывает, что модуль OverseeWebSite получает от процедуры Process Incoming-Customer информацию о каждом покупателе и передает ее процедуре OverseeBrowsing, от которой получает готовый бланк заказа и передает его процедуре ProcessOrder.

Минимальная зависимость между модулями системы — одно из главных преимуществ объектно-ориентированного программирования. И в самом деле, основная идея объекта состоит в том, чтобы поместить процедуры, манипулирующие одними данными, в один модуль. Поэтому в объектно-ориентированных системах межмодульная связь принимает форму взаимодействия между объектами, которое обычно реализуется как связь по управлению. То есть, когда мы требуем выполнения объектом какой-либо задачи, по существу, мы требуем выполнения метода (процедуры) этого объекта. Поэтому запрос, в результате которого управление передается объекту, подобен передаче управления процедуре в императивном программировании.

Для изображения взаимодействия между объектами обычно используется диаграмма взаимодействия (collaboration diagram), которая, в сущности, является диаграммой классов, показывающей взаимодействие разных объектов системы. Простая диаграмма взаимодействия (построенная с использованием UML-co-вместимого представления) для системы заказа товаров через Интернет (рис. 6.6) показывает, что объект типа Customer посылает сообщение объекту OrderForm с предписанием добавить/удалить элемент в бланк заказа, а объект типа Catalogue посылает сообщение, содержащее информацию о конкретном товаре, объекту Customer.

Независимо от того, какой тип связи модулей используется, программист должен стремиться к тому, чтобы эта связь была очевидной. Замаскированная связь, называемая неявной связью (implicit coupling), порой приводит к ошибкам в системе программного обеспечения. Неявная связь часто является результатом использования глобальных данных (global data), то есть элементов данных, которые автоматически доступны всем модулям системы, в отличие от локальных элементов данных, которые доступны только определенному модулю, если их не передать явным образом другому модулю. Большинство языков программирования высокого уровня предоставляют средства реализации как глобальных, так и локальных данных. Трудность использования глобальных данных состоит в том, что изменение их часто является побочным эффектом, а не выражается явно. (В программировании термин «побочный эффект» (side effect) используется по отношению к действию системы программного обеспечения, которое явно не указано в тексте программы.) Человек, читающий программу, может не догадаться, что модуль изменяет глобальные данные, пока не рассмотрит более подробно внутреннее строение модуля. Это уменьшает полезность модуля как абстрактного инструмента. (Еще один пример необходимости использования комментариев — чтобы помочь читателю понять программу.)

Связность модуля

Сделать максимальной связь элементов внутри каждого модуля не менее важно, чем минимизировать межмодульные связи системы. Термином связность (cohesion) обозначается степень связанности внутренних частей модуля. Для того чтобы понять важность связности элементов модуля, необходимо рассмотреть не только разработку системы программного обеспечения, а весь ее жизненный цикл. Если потребуется внести в модуль какие-либо изменения, наличие в нем большого количества функций может осложнить изначально простую задачу. Поэтому, помимо небольшой межмодульной связи системы, разработчики программного обеспечения стремятся к высокой связности элементов модуля.

Логическая связность (logical cohesion) является слабым видом сцепления элементов модуля, при котором внутренние элементы модуля выполняют логически сходные действия. Рассмотрим, например, модуль, осуществляющий взаимодействие системы с внешним миром. «Клеем», соединяющим его в единое целое, является то, что все его процедуры обрабатывают информацию. Однако их действия могут быть совершенно разными. Некоторые процедуры могут получать данные, а другие, например, выводить сообщения об ошибках.

Функциональная связность (functional cohesion) представляет собой более сильное сцепление, при котором все части модуля обеспечивают выполнение одной задачи. Например, модуль OverseeBrowsing (см. рис. 6.3) не является функционально связным, поскольку он содержит процедуры, осуществляющие общение с покупателем, получающие и отображающие информацию о товарах и создающие бланк заказа покупателя. Однако если эти процедуры поместить в отдельные модули и использовать их в качестве абстрактных инструментов, то модуль OverseeBrowsing будет контролировать действия, связанные с просмотром каталога, что делает его более функционально связным.

В объектно-ориентированной системе объекты обычно связаны только логически, поскольку методы объекта, как правило, выполняют действия, практически не связанные между собой. При этом их объединяет только то, что они являются методами одного объекта. Например, в системе заказа товаров через Интернет каждый объект бланка заказа, вероятно, будет содержать метод, добавляющий элемент к заказу, удаляющий элемент из заказа и отправляющий заказ. Следовательно, такой объект будет представлять собой логически связный модуль.

Однако создатель программного обеспечения должен стремиться к тому, чтобы каждый отдельный метод объекта был функционально связным. То есть, даже если сам объект является только логически связным, каждый метод объекта должен выполнять только функционально связную задачу (рис. 6.7).


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: