диспетчеризация

ООП, мультиметоды диспетчеризация пирамидальная эволюция- Открытые системы 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 кожгалантерея диспетчеризация