диспетчеризация
ООП, мультиметоды диспетчеризация пирамидальная эволюция- Открытые системы
table.block_body {
background-color: #006677;
}
td.block_body {
background-color: #ffffff;
}
div.block_title {
background-color: #006677;
color: #ffffff;
font-weight: bold;
margin-left: 20pt;
}
a.block_title {
color: #ffffff;
}
div {
font-size: small;
}
td {
font-size: small;
}
tr.table_header {
background-color: #ccccff;
}
Войти в систему
Регистрация
Настройка
Форум
RSS
Поиск:
Весь сервер
_______________
НОВОСТИ
Computerworld
Мир ПК
Открытые системы
Windows IT Pro
LAN
Сети
Директор ИС
Расширенный поиск
Издания
Новости
Конференции
Обучение
Компаниям
Об издательстве
Подписка
Computerworld Сети Директор ИС LAN Windows IT Pro Открытые системы Мир ПК
Открытые системы
От редакции
Новости
Платформы
Менеджмент ИТ
Интеграция
Разное
Приложения
Безопасность
Программная инженерия
Стандарты
Академия ОС
Книжная полка ОС
Все статьи номера
Архив номеров
Alt.CW
Xacti CG9 - новый цифровой камкордер Sanyo, представляющий собой,...
Четвертого апреля в США вот уже пятый год подряд...
Специалисты Университета Калифорнии в Сан-Диего изобрели алгоритм распознавания границ...
Преподаватель Хьюстонского университета Брайан Макфарлин провел сравнительное тестирование двух...
Разное
ООП, мультиметоды диспетчеризация пирамидальная эволюция
К достоинствам объектно-ориентированного подхода относится поддержка эволюционной разработки, что позволяет наращивать функциональность, не изменяя существующий код.
Александр Легалов
К достоинствам объектно-ориентированного подхода относится поддержка эволюционной разработки, что позволяет наращивать функциональность, не изменяя существующий код. Однако реализация мультиметодов порождает определенные проблемы диспетчеризация зачастую ведет к использованию приемов из арсенала процедурного программирования. В статье рассмотрен ряд трюков, позволяющих удержаться в русле объектной ориентации.Достаточно часто возникают ситуации, когда гомоморфные иерархии, определяемые как иерархии классов с одинаковым открытым интерфейсом, унаследованным от общего базового класса [1], взаимодействуют через функцию, виртуальную к произвольному числу полиморфных параметров. Такая функция называется мультиметодом [2], диспетчеризация возможность ее использования существует в языке программирования CLOS (Common Lisp Object System). Однако широко распространенные объектно-ориентированные языки программирования не поддерживают подобный механизм в связи с отсутствием его эффективной реализации [3].Традиционные подходыДля иллюстрации воспользуемся вычитанием чисел, задаваемых соответствующими классами. Числами манипулировал диспетчеризация Джефф Элджер [1], Скотт Мейерс в подобной ситуации сталкивал разнородные космические объекты [2], диспетчеризация Бьерн Страуструп занимался пересечением геометрических фигур [3].Самый простой вариант, опирающийся на объектно-ориентированный подход, заключается в использовании виртуального метода для определения типа первого аргумента. Второй аргумент выявляется с помощью RTTI (runtime type identification — «идентификация типов во время выполнения») [2]. Классы, входящие в гомоморфную иерархию, реализованы следующим образом:class Number {public:// Вычитание второго аргумента из данногоvirtual Number* Subtract(Number& num2) = 0;virtual void StdOut() = 0;};class Int: public Number {public:// Вычитание второго аргумента из целочисленногоNumber* Subtract(Number& num2);void StdOut();Int(int v): _value(v) { } // конструкторint GetValue() {return _value;} // получение значенияprivate:int _value; };class Double: public Number {public:// Вычитание второго аргумента из действительногоNumber* Subtract(Number& num2);void StdOut();Double(double v): _value(v) { } // конструкторdouble GetValue() {return _value;} // получение значенияprivate:double _value; };Метод StdOut, осуществляющий вывод значения числа, используется только для тестирования диспетчеризация в дальнейшем не рассматривается. Производные классы реализуют вычитание из себя второго аргумента, динамически выявляя его тип:Number* Int::Subtract(Number& num2) {// Второй аргумент - целое числоif(Int* pInt = dynamic_cast(&num2)) {return new Int(_value - pInt->GetValue()); }// Второй аргумент - действительное числоelse if(Double* pDouble = dynamic_cast(&num2)) {return new Double(_value - pDouble->GetValue()); }else { return 0; } }Number* Double::Subtract(Number& num2) {// Второй аргумент - целое числоif(Int* pInt = dynamic_cast(&num2)) {return new Double(_value - pInt->GetValue()); }// Второй аргумент - действительное числоelse if(Double* pDouble = dynamic_cast(&num2)) {return new Double(_value - pDouble->GetValue()); }else { return 0; } }Мультиметод, выполняющий вычитание, обращается к методу класса, инициирующему диспетчеризацию:Number* operator - (Number& n1,Number& n2) {return n1.Subtract(n2); }К недостаткам следует отнести изменение методов во всех производных классах при добавлении новой разновидности чисел, например, комплексных. Кроме этого, с увеличением числа альтернатив, замедляется анализ вариантов.Более быстрым является чисто объектно-ориентированное решение, на основе двойной диспетчеризации [1]. Она делит монолитную операцию на два метода, каждый из которых определяет тип первого диспетчеризация второго операнда, используя полиморфизм. Базовый класс задает весь необходимый интерфейс:class Number {public:virtual Number* Subtract(Number& num2) = 0;virtual Number* SubtFromInt(int v) = 0;virtual Number* SubtFromDouble(double v) = 0;virtual void StdOut() = 0;};Метод Subtract инициирует вычитание диспетчеризация определяет тип первого числа. Для получения типа второго числа необходимы функции, вычитающие значения текущих объектов из передаваемых им первых аргументов. Эти методы тоже прописываются в базовом классе; производные классы обеспечивают реализацию в соответствии с характеристиками моделируемых объектов.class Int: public Number {public:Number* Subtract(Number& num2);Number* SubtFromInt(int v);Number* SubtFromDouble(double v);void StdOut();Int(int v) : _value(v) { }private:int _value;};class Double: public Number {public:Number* Subtract(Number& num2);Number* SubtFromInt(int v);Number* SubtFromDouble(double v);void StdOut();Double(double v) : _value(v) { }private:double _value;};// — Реализация методов —// Диспетчеризация при первом целом аргументеNumber* Int::Subtract(Number& num2) {return num2.SubtFromInt(_value);}Number* Int::SubtFromInt(int v) {return new Int(v - _value);}Number* Int::SubtFromDouble(double v) {return new Double(v - _value);}// Диспетчеризация при первом действительном аргументеNumber* Double::Subtract(Number& num2) {return num2.SubtFromDouble(_value);}Number* Double::SubtFromInt(int v) {return new Double(v - _value);}Number* Double::SubtFromDouble(double v) {return new Double(v - _value); }Двойная диспетчеризация тоже не подходит для эволюционного программирования, поскольку как добавление нового класса ведет к переопределению интерфейсов всей, уже существующей, гомоморфной иерархии.Для исправления ситуации в [2] предложена смесь из RTTI, ассоциативных массивов диспетчеризация процедурного подхода. Не сомневаясь в возможности использования подобного решения, я все же решил попробовать «построить эволюцию» только с применением классов. В результате возник ряд трюков, целесообразность которых диспетчеризация выносится на обсуждение.Нужна ли всеобщая универсальность?Основной причиной, заставляющей изменять разработанные классы, является стремление обеспечить их универсальность по отношению к новым понятиям. Например, при реализации функции F(A1, A2), задающей взаимодействие двух гомоморфных агентов, всегда формируется матрица отношений.При ее объектно-ориентированной реализации проявляется один из «порочных» принципов: каждый агент должен сам уметь обрабатывать себя. Следовательно, эволюционное появление новых классов, осуществляющих взаимодействие с уже существующими, ведет к необходимости «революционной» адаптации, реализуемой через внедрение в «старые» классы дополнительных связей.Вместе с тем, эволюционное расширение изначально предполагает естественную упорядоченность новых понятий в порядке поступления. Этим можно воспользоваться, если установить, что добавляемый класс будет нести нагрузку по взаимодействию с существующими. Старый класс только должен уметь предоставлять информацию, необходимую для новых связей. При этом можно применить обычный объектно-ориентированный полиморфизм для выбора первого аргумента мультиметода. Схематически результат подобного решения можно представить в виде треугольника, клетки которого, расположенные ниже главной диагонали ранее существовавшего квадрата, содержат по два обработчика: свой диспетчеризация «того парня».Чтобы не именовать подобный прием «треугольным», мысленно добавим третий аргумент диспетчеризация представим образ пирамиды. Подыскать соответствующую реализацию этой концептуальной схеме в виде пирамидальных классов — дело техники.Поголовное использование RTTIСамый простой диспетчеризация эффективный способ — использование RTTI для идентификации второго аргумента. Ее осуществляет первый аргумент, выход на который осуществляется по всем канонам объектно-ориентированного программирования. Если класс второго аргумента, в эволюционной иерархии, находится выше первого, то нет проблем реализовать в нем метод обработки. А что делать, если наоборот? Тогда достаточно вызвать метод, полиморфно перенаправляющий первый аргумент второму. А тот, с помощью RTTI, разберется. Подобная схема допускает наследование только от общего абстрактного базового класса всех членов гомоморфной иерархии.Рассмотрим реализацию вычитания. Класс Number задает интерфейсы, определяющие взаимодействие внутри эволюционной пирамиды. Метод Subtract осуществляет полиморфную идентификацию первого аргумента. Вспомогательный метод SubtFrom предназначен для выявления второго аргумента в том случае, если он располагается в иерархии ниже первого. То есть, метод используется для доступа к виртуальным функциям, обеспечивающим взаимодействие текущего класса с более поздними членами эволюционной цепочки.class Number {public:virtual Number* Subtract(Number& num2) = 0;virtual Number* SubtFrom(Number& num1) = 0;virtual void StdOut() = 0;};Разместим на вершине иерархии класс целых чисел (или любой другой). Он переопределяет методы, наследуемые от Number. Дополнительный метод GetValue предназначен для непосредственного доступа к значению из классов — продолжателей эволюционной цепочки.class Int: public Number {public:Number* Subtract(Number& num2);Number* SubtFrom(Number& num1);void StdOut();Int(int v) : _value(v) {}int GetValue() {return _value;}private:int _value; };Метод Subtract динамически проверяет второй аргумент на принадлежность к целым числам диспетчеризация выполняет вычитание. Если же второй аргумент не является числом известного типа, вызывается метод, перенаправляющий его одному из виртуальных обработчиков SubtFrom.Number* Int::Subtract(Number& num2) {if(Int* pInt = dynamic_cast(&num2)) {return new Int(pInt->GetValue() -_value); }else {return num2.SubtFrom(*this);}}Так как целочисленный класс никого, кроме себя, «не знает», то его собственный обработчик SubtFrom используется в качестве заглушки. Все классы, разработанные позднее, будут сами отвечать за свое взаимодействие с Int. В методе SubtFrom может находиться генератор исключений, сигнализирующий о появлении числа неизвестного типа. Такая ситуация вполне возможна диспетчеризация будет рассмотрена ниже.
1 2 3 >>
22.03.2002г.
Также в разделе
Вечнозеленая тема
Российская индустрия программирования
22/03/2002 №03
Удовольствие
Будьте готовы к быстрым методам
Параллельные программы для вычислительных кластеров диспетчеризация сетей
Анализ качества баз данных
СОДЕРЖАНИЕ
От редакции
Формула успеха
Платформы
Онтология промежуточного ПО
Виртуальный кластер из консервной банки
Параллельные программы для вычислительных кластеров диспетчеризация сетей
Анализ качества баз данных
Менеджмент ИТ
Методы XP диспетчеризация сопровождение программ
Экстремальное программирование с позиций CMM
Разное
ООП, мультиметоды диспетчеризация пирамидальная эволюция
Вечнозеленая тема
Российская индустрия программирования
Академия ОС
Подготовка бакалавров диспетчеризация магистров в области ИТ
Памяти Digital Equipment Corporation (1957 — 1998)
Книжная полка ОС
Удовольствие
Будьте готовы к быстрым методам
Эта рубрика в архиве
Список номеров за
2008
2007
2006
2005
2004
2003
2002
2001
2000
1999
1998
1997
1996
1995
1994
1993
01
02
03
04
05
06
07-08
09
10
11
12
Партнёры сайта:
От партнёров:
Загружается, подождите...
Сми2
ИноСМИ.Ru:
МаркетГид:
Обзор...
Загружается, подождите...
Об издательстве Авторские права Как нас найти Реклама Контакты
Издания:
Computerworld
Windows IT Pro
LAN
Сети
Мир ПК
Открытые системы
Директор ИС
WhatCar?
ФСП
Publish
Классный журнал
Stuff
Oil&Gas
Лечащий врач
Copyright © 1992-2008. All rights reserved.
разделы
ppg краска
кулер бесшумный
культура танго
слименд лифт
гипсокартон
купить архиватор
роль ставень
кристофер брэнд
восстановление удаленный информация
кострома риелтор
вызов врач
изготовление краска
пошив корпоративный костюм
болен алкоголизмом
калибровка цвет
купить архиватор
роль ставень
дружкова кружка
применение доломита
помыть потолок
букмекерский контора шанс
отчетность пбоюл
северский доломит
планирование день
съемный зубной протез
поставка тройник перех
инерта краска
лечение щитовидный железа
подготовка ielts
кострома риелтор
огнезащитный покрытие
пионовая беседка
эфирный антенна
оповещение
аэробика
охота гончий
нужный билет
бюгельные зубной протез
морозильный ларь
бак накопитель
танго кэш
герб вышивка
стимулирующий лотерея
5440.14 (крышка)
кулер 754
мустанг лазер
мужчина выходной
рак пищевод
ваза 2110
инженерный геодезия
эдас-134 аденома предст.ж-зы
устройство плавный пуск
ваза 2115
оповещение
затенение витрина
шампанский заказ
организация похорон
sharp ar-5415
аэробика
купить букмекерский линия
dhl
индивидуальный банковский ячейка
аэробика
мрт коленный сустав
узи тошиба
тройник
поставка тройник
анкетирование
тач-скрин монитор
добрый тепло
gislaved отзыв
угловой тестомесители
tognana фарфор
очки защитный
газонокосилка elmos
вино заказ
грунт
пп-пленка
встраиваемый вытяжка
peg perego venezia
зиплок
клеить нанесение
дренаж
dhl
краска двухкомпонентный
слим лифт
электрокамин dimplex model magic (sp8)
маркировочная краска
магнитный решетка
врач акушер гинеколог
фейрверк праздник
фасадный покрытие
вытяжка крона
motorola v3i купить
решетка
плата видеозахвата
продать кайт
новосельский доломит
шарошка алмазный
бак накопитель
стелажи
аденома
врач-гинеколог
кулер тихий
аэробика
герб область
macintosh
система видеоконференция
гостинницы спб
покраска рчв
виниловый дирижабль
8800 gold
антигололедные реагент
neri karra кожгалантерея
диспетчеризация