[ <<< | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Источники | >>> ]
© 2001 А.И. Легалов
Агрегация (агрегирование) - это абстрагирование, посредством которого один объект конструируется из других [Цикритзис]. В связи с тем, что на самом нижнем уровне в программировании нами выделены две базовые абстракции (данные и процедуры), построение агрегатов может происходить следующими путями:
Необходимо отметить, что в данном случае под агрегированием подразумевается не просто размещение (вложение) одних абстракций в других. Оно рассматривается как конструирование новых программных объектов (данных, процедур и смешанных конструкций), из существующих. Следует отметить, что тело процедуры также можно рассматривать как агрегат, состоящий из команд и вызовов процедур. Но в данной работе этот вопрос обсуждаться не будет.
Следует понимать, что понятие "агрегат" является более узким, чем такие распространенные понятия, как модуль, пространство имен, класс. Оно определяет конструкцию, в которой основной акцент делается на композицию объектов, имеющих ресурсную привязку. Именно к таким объектам и относятся переменные с процедурами. Переменные размещаются в отведенном адресном пространстве и используются исключительно для хранения данных. Процедуры также должны храниться в памяти, хотя их использование более многогранно. Может осуществляться многократное тиражирование отдельных частей процедуры, таких как область локальных данных и тело. Это тиражирование производится во время вызовов процедур, а его характер определяется как архитектурой вычислительной системы, выполняющей программу, так и особенностями языка программирования высокого уровня. Например, вызов процедур в некоторых параллельных системах организован иначе, чем в последовательных компьютерах. Наряду с данными и процедурами общепринятые модульные конструкции используются для хранения АТД и других программных объектов, не занимающих ресурсов и используемых только во время компиляции программы. Тем самым обеспечивается локализация области видимости имен, что используется для борьбы со сложностью и сокрытия информации. Вместе с тем, размещение в традиционных модульных конструкциях объектов, располагаемых в памяти, позволяет говорить о них как об агрегатах, игнорируя при этом прочие понятия.
Агрегирование обеспечивает формирование программных объектов одним из способов: непосредственным включением, косвенным (ссылочным) связыванием, с применением наследования (расширения) и образного восприятия.
Наиболее типичным является восприятие агрегата как единой абстракции, сформированной непосредственным включением используемых в нем программных объектов. В нашем сознании он видится как единый, монолитный ресурс, занимающий некоторое неразрывное пространство (почему-то в моем сознании чаще всего возникает плоскость:). На рис. 1а агрегат, сформированный непосредственным включением элементов отображен в двухмерном пространстве. Отображение такого агрегата на фрагмент одномерного пространства памяти приведено на рис. 1б.
Цельность и законченность данного объекта не требует выполнения дополнительных алгоритмов, связанных с формированием его структуры. Можно сразу приступать к алгоритмическому использованию объекта, например, его инициализации.
Косвенное связывание позволяет формировать агрегаты из отдельных элементов, уже располагаемых в пространстве. Взаимосвязь осуществляется алгоритмическим заданием значений ссылок. Спецификой является необходимость выполнения кода обеспечивающего конструирование объекта из разрозненных экземпляров абстракций. Однако этот код выполняется только один раз, после чего работа с агрегатом осуществляется точно так же, как и в предыдущем случае. В ряде случаев, когда элементы и агрегат создаются статически, инициализация связей может быть проведена во время трансляции программы. Образный пример агрегата, построенного с применением косвенного связывания, представлен на рис. 2.
Применение наследования позволяет создавать структуру объекта, эквивалентную той, которая формируется непосредственным включением. Однако наследование дополнительно подерживает свойства конкатенации (слияния), в результате чего обращение к элементам подключаемых абстракций осуществляется напрямую, не затрагивая имена добавляемых абстракций. При этом, в отличие от конкатенации, сохраняется информация о базовых абстракциях, которая может использоваться для разрешения проблем неоднозначности доступа к элементам сформированного агрегата при совпадении их имен. Кроме того, в отличие от непосредственного включения, каждому наследуемому элементу "предоставляется" дополнительная информация о формируемом агрегате. Эта информация может быть "задана" специальными методами построения агрегата или за счет введения дополнительных внутренних переменных, инициализируемых во время конструирования объекта. Использование дополнительной информации позволяет правильно манипулировать агрегатом, используя лишь сведения об одном из его базовых (включаемых) элементов. Например, через базовый элемент можно определить тип агрегата, его размер, выполнить операцию удаления. Упрощенное графическое представление агрегата, построенного с использованием наследования, приведено на рис. 3.
Образное агрегирование связано с отсутствием специально созданной абстракции, соответствующей формируемому агрегату. Вместо этого агрегат воссоздается только в мысленном восприятии программиста, а на уровне программы имеются его отдельные элементы, обрабатываемых как единое целое. Например, точку на плоскости можно представить как две независимые целочисленные переменные x и y. Конечно, такое агрегирование уходит корнями в далекое прошлое (эпоху Фортрана и Алгола-60), но и сейчас встречаются программисты, которым "лень" вписать лишнюю абстракцию. Это приводит к определенным проблемам, связанным с мобильностью и повторным использованием кода, но иногда так хочется поскорее написать программу, что не остается времени на раздумья о стиле! Графическая интерпретация образного агрегата приведена на рис. 4.
Вполне очевидно, что, наряду с "чистыми" методами, агрегаты могут строиться по смешанному принципу, когда одновременно применяются различные комбинации методов агрегирования. В качестве примера на рис. 5 представлен агрегат, выстроенный с применением включения, косвенного связывания и наследования.
Именно такой подход и является наиболее популярным в настоящее время, так как позволяет рационально использовать различную технику в зависимости от организации и назначения агрегируемых элементов. Можно, конечно, подключать и образное восприятие, но мне кажется, что в подавляющем большинстве случаев проще сформировать еще одну абстракцию, зафиксировав, тем самым, используемое решение "документально".
Возможно, у Вас возник вполне закономерный вопрос: от чего я впал в маразм и подробно привел прописные истины? А чтобы подчеркнуть, что различные способы организации программных объектов отображаются в виде определенных стереотипов в наших затуманенных мозгах, что во многом и определяет приверженность выбранному стилю программирования.
К специфике различных парадигм программирования можно отнести способы построения агрегатов и их использования. В частности, при процедурном программировании осуществляется разделение на агрегаты данных и процедур. Объектно-ориентированный подход использует комбинированное агрегирование. Ниже рассмотрены особенности построения и использования агрегатов для этих парадигм.
[ <<< | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Источники | >>> ]