[ <<< | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Источники | >>> ]


© 2001 А.И. Легалов

Объектное обобщение

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

Первый агрегат, являясь экземпляром производного или базового класса, содержит данные и процедуры, непосредственно размещенные в его теле. Для различных производных классов состав этих данных и процедур может отличаться, так как не они определяют облик формируемого обобщения.

Внутри этого агрегата существует вторая, статическая связь, формируемая во время компиляции. Она присоединяет агрегат, состоящий из виртуальных (переопределяемых) процедур, обеспечивающих обработку специализации обобщения. Этот агрегат процедур (а не таблица виртуальных функций с указателями на процедуры) может заменяться на другой при построении производного класса. Именно разделение на две конструкции способствует гибкой смене специализированных процедур в ходе разработки программы, которое внешне выглядит как замещение виртуальных процедур базового класса процедурами производного класса. При этом сигнатуры альтернативных процедур, определяемых базовым классом, не меняются. Непосредственный доступ из виртуальных процедур к переменным класса позволяет гибко подстраивать процесс обработки данных под специфику производных классов.

Реализация такого связывания осуществляется на основе механизмов наследования и виртуализации, являющихся общепринятыми в ОО подходе. Они позволяют создать иерархию классов, расширяемую по самым различным направлениям. Общая схема возможной иерархии классов приведена на рис. 10.

Каждый из классов этой иерархии может служить альтернативой в объектном обобщении, порождаемом на основе базового класса. Следует отметить, что, в общем случае, количество виртуальных процедур, а также агрегативных процедур и данных в порождаемых производных классах может увеличиваться. Однако, структура интерфейса, определяемая базовым классом, остается неизменной, что и позволяет, на этой основе, выстраивать механизм анализа альтернатив.

Основная задача выбора альтернативы заключается в вызове соответствующей процедуры. Она решается следующим образом. Через указатель на экземпляр базового класса, обеспечивающий динамическое связывание с любым экземпляром производного класса, осуществляется доступ к интерфейсу объекта. Назовем такой указатель опорой объектного обобщения. Схема возможных динамических подключений для ранее рассмотренной иерархии классов представлена на рис. 11.

Альтернатива создается во время выполнения программы, предоставляя в наше распоряжение набор специализированных процедур, к которым происходит обращение через второй указатель, обеспечивающий статическое связывание. Как и многие предшествующие мне ораторы, хочу еще раз отметить, что подобная структура является не единственной, и двойное связывание может быть реализовано различными способами.

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

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

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

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

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

Обработка обобщений обычно осуществляется виртуальными процедурами производных классов, которые переписываются в соответствии с их специализацией. Эти процедуры назовем расширяющими процедурами. При этом процедура базового класса (опорная процедура) может использоваться там, где ее функциональных возможностей достаточно. В объектном обобщении осуществляется привязка процедур классов к объектам, что ведет к централизации функционального интерфейса. Декомпозиция функций производится путем распределения каждой процедуры по своим специализациям, заданным производными классами.


[ <<< | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Источники | >>> ]