307
В чем же разница между этими двумя способами? В случае непрямой инкапсу"
ляции реализация абстрактного типа данных действительно не зависит от его ис"
пользования. Если потребуется изменить внутреннюю структуру объекта
P, то при"
дется менять только пакет A. Пакету B только необходимо «знать», что объект P
является просто указателем, а формат данных, на который указывает P, для пакета B
не имеет значения. Способ непрямой инкапсуляции хорош для больших программ,
содержащих тысячи модулей, так как отпадает необходимость заново компилиро"
вать каждый модуль, где используется объект, определение которого поменялось;
за счет этого можно значительно сэкономить время.
Но, с другой стороны, при использовании этого способа дополнительное время
тратится на доступ к инкапсулированным объектам при выполнении программы.
Доступ к объекту P каждый раз подразумевает обращение к указателю на этот
объект. Хотя само по себе это действие не связано со значительными затратами
времени, многократное обращение к объекту через указатель может оказаться до"
вольно дорогостоящим.
Прямая инкапсуляция характеризуется прямо противоположными свойства"
ми. В данном случае объект данных
P хранится в записи активации пакета B. До"
ступ к компонентам объекта P теперь может быть осуществлен быстрее, поскольку
в пределах локальной записи активации можно применить стандартную технику
доступа к объектам данных по формуле áàçîâûé àäðåñ + ñäâèã; в данном случае не
требуется никаких промежуточных указателей. Но если представление объекта
данных меняется, то все пакеты (например, пакет B), в которых этот объект ис"
пользуется, должны быть заново скомпилированы. Это увеличивает затраты на
компиляцию, но ускоряет выполнение программы.
В языке Ada используется прямая модель инкапсуляции, которая обеспечива"
ет максимальную эффективность выполнения программы. При трансляции исполь"
зуемого в пакете объекта абстрактного типа (например, объекта P в пакете B на
рис. 7.1, б) требуется информация о деталях представления объекта. Этим и объяс"
няется необходимость раздела private в спецификации пакета.
Заметим, однако, что и прямая, и непрямая модели инкапсуляции могут ис"
пользоваться в любой программе, поддерживающей инкапсуляцию, независимо
от модели, реализованной как часть программной архитектуры используемого язы"
ка программирования. Хотя в реализации самого языка Ada предпочтение отдано
модели прямой инкапсуляции, которая и используется в нем по умолчанию, не"
прямая инкапсуляция может быть реализована самим программистом. В листин"
гах 7.2 и 7.3 приведены фрагменты пакетов Ada, демонстрирующие применение
обеих стратегий реализации инкапсуляции. Листинг 7.2 соответствует модели, схе"
матически изображенной на рис. 7.1, а (access — переменная"указатель в языке Ada),
а листинг 7.3 — модели, представленной на рис. 7.1, б.
Листинг 7.2. Пример непрямой инкапсуляции данных в языке Ada
package A is
type MyStack is private;
procedure NewStack(S: out MyStack);
…
private
type MyStackRep;
продолжение ®
7.1. Повторное рассмотрение абстрактных типов данных