Главная » Просмотр файлов » А. Александреску - Современное проектирование на C++

А. Александреску - Современное проектирование на C++ (1119444), страница 55

Файл №1119444 А. Александреску - Современное проектирование на C++ (А. Александреску - Современное проектирование на C++) 55 страницаА. Александреску - Современное проектирование на C++ (1119444) страница 552019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 55)

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

Это проше и быстрее, но ассоциативный массив все же лучше. Индексы в таком массиве не обязаны быть смежными. Кроме того, в векторе индексы могут быть только целыми числами, в то время как индексом ассоциативного массива может быть любой тип, для которого установлено отношение порядка. При обобщении нашего примера этот факт приобретает особое значение. Начнем с разработки класса 5бареяассогу, предназначенного для создания всех объектов классов, производных от класса 5ьаре. В реализации класса 5пареяастогу мы будем использовать ассоциативный массив из стандартной библиотеки зтб::вар. с1ааа 5пареяассогу ( Глава 8. Фабрики объвктов рцЫ1с: туреде1 5ьаре* (*сгеатезьареса11ьаск) О; рг1чате: туредет зад::шар<бит, сгеатезьареса11Ьасм> са11ьасхмар; рцЫ1с: // возвращает значение тгце, если регистрация прошла успешно Ьоо) яецэ'зтег5Ьаре(э'пт 5Ьарехд, СгеатезпареСа11Ьаск Сгеатенй); // возвращает значение тгце, если фигура 5Ьарехд // уже зарегистрирована Ьоо1 цпгецэ'зтегед5Ьаре(дпт 5Ьарехд); 5Ьаре+ Сгеате5Ьаре(бпт 5Ьаретд); ргд часе: са11Ьасймар са11Ьаскз Зто общая схема масштабируемой фабрики.

Фабрика является масштабируемой, поскольку при добавлении нового класса, производного от класса 5Ьаре, в код нс нужно вносить никаких изменений. Класс 5Ьаренастогу разделяет ответственность: каждая новая фигура должна зарегистрироваться в фабрике, вызвав функцию яец1з- тег5Ьаре и передав сй целочисленный идентификатор и указатель на функцию, соз- дающую объект. Обычно эта функция состоит всего иэ одной строки. 5ьаре'е сгеатеьдпеО ( гетцгп пеш ьбпе; ) 1 Реализация класса ~Лпе также должна зарегистрировать эту функцию в объекте класса 5Ьарерастогу, используемом в приложении.

Обычно доступ к этому объекту является глобальным.' Регистрация выполняется вместе с инициализацией. Связь класса Ь1 пе с фабрикой 5Ьарерастогу устанавливается следующим образом. // Модуль реализации класса ьэ'пе // создаем безымянное пространство имен, // чтобы сделать функцию невидимой из других модулей пашезрасе ( 5Ьаре' сгеатеь1пеО ( гетцгп пеш ьэ'пе; // идентификатор класса ьдпе сопят дпт ьхйе Х; // дойустим, что фабрика тЬе5Ьарерастогу— // фабрика синглтоиов(си. главу 6) сонат Ьоо1 гец1зтегед = тьезьарерастогу::хпзтапсеО .йец1зтегбьаре( ьхне, сгеатеьэпе); Благодаря воэможностям, предоставленным стацдартным ассоциативным массивом зтд::юар, класс 5Ьарерастогу реализуется легко, По существу, функции-члены класса 5Ьарерастогу переадресуют аргументы функции-члену са11Ьасй .

э Это устанавливает связь между фабриками объектов и синглтонами. Действительно, а большинстве случаев фабрики лачлютса синглтонами. Ниже а этой главе мы обсудим, как используются фабрики с сииглтонами, описанными а главе б. 224 Чаоть П. Компоненты Ьоо1 ЗЬарегассогу::яео1зсегЗЬаре((пс зЬаресд, сгеасезЬареса11Ьаск сгеасегп) ( гесигп са11Ьас)с .1пзегс( са11Ьаскмар: гыа1це суре(збаресд, сгеасекп)).зесопд; ) Ьоо1 зЬаресассогу::цпгей(зсегзбаре(1пс зЬаресд) ( гесцгп са11Ьасйз .егазе(зЬаретд) == 1; Если вы не знакомы с шаблонным классом зсд::юар, предыдущий код нужаается в пояснениях.

° Класс зсд::юар содержит пары, состоящие из ключей и данных. В нашем случае ключами являются целочисленные идентификаторы фигур, а данные состоят из указателя на функцию. Такие пары имеют тип зсд::раз г<сопзс зпс, сгеасезбареса1!ЬасК>. При вызове функции зпзегс нужно передавать ей объект этого типа. Поскольку это выражение слишком длинное, в классе зсд::вар используется его синоним ча1ое суре. В качестве альтернативы можно использовать также тип зсд::юане ра1г.

° Функция-член )пзегс возвращает другую пару, на этот раз состоящую из итератора (ссгклаюшегося на только что вставленный элемент) и булевской переменной, принимающей значение сгце, если значения в ассоциативном массиве до этого момента не было, и та1зе — в противном случае. ° Функция-член егазе возвращает количество удаленных элементов.

Функция-член сгеасезбаре просто извлекает указатель на функцию, соответствующий полученному идентификатору типа, и вызывает ее. Если возникает ошибка, генерируется исключительная ситуация. ЗЬаре~ зЬарекассогу::Сгеатевбаре(зпс збаретд) ( са11Ьаскмар::сопзс 1сегасог 1 = са11Ьаскз .Лпд(зЬаретд); 11 (з == са11Ьаскз .епдО) ( // не найден сбгоы зсд::гцпсзюе еггог("неизвестный идентификатор"); ) // вызываем функцию для создания объекта гесцгп ((->зесопд) и; ) Посмотрим, что дает нам этот простой класс.

Вместо громоздкого оператора зкп ссЬ мы получили динамическую схему, требующую, чтобы каждый тип регистрировался в фабрике. Это распределяет ответственность между классами. Теперь, определяя новый класс, производный от класса збаре, можно просто добавлягаь файлы, а не модифицировать их. 8.4. Идентификаторы типов Осталась одна проблема — управление идентификаторами типов, По-прежнему добавление новых идентификаторов типов требует дисциплинированности и централизованного контроля. Добавляя новый класс, программист обязан проверять все существующие идентификаторы типов, чтобы новый идентификатор не совпал со старыми. Если все же совпадение произошло, второй вызов функции-члена яео- 225 Глава 8. Фабрики объектов т вгегбйаре с тем же самым идентификатором не выполняется, и объект этого типа не созлается.

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

Если вы проводите каникулы, изучая язык С++, предыдущий параграф будет для вас предупредительным сигналом. Давайте попробуем применить класс туре того! Класс зтд::туре (пто является частью информации о типах времени выполнения программы (Кцпйгпе Туре 1п(оппайоп — КТТ1)„предусмотренных языком С+и.. Ссылку на класс втд: г буре з'пбо можно получить, применив оператор туре(д к типу или выражению. Класс зтд::туре (пго содержит функциюошен ламе, возвращающую указатель типа сопзт сваг*, ссылающийся на имя типа. Указатель, возвращаемый оператором сурет депе) . ламе О, ссылается на строку "с) аз в ь(пе", что и требовалось.

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

Живучесть реализации — важное качество фабрик, а функция втд::туре (пго::ламе является неусгиойчивой. Итак, хотя класс в гд:: суре з пЕо на первый взгляд подходит для создания фабрик, на самом деле он совершенно неприемлем. Вернемся к вопросу об управлении идентификаторами типов. Генерировать идентификаторы можно с помощью датчика случайных чисел. Этот датчик нужно вызывать каждый раз, когда создается новый объект. При этом новое значение следует запомнить и больше никогда не изменять.' Это решение кажется довольно примитивным, однако вероятность того, что за тысячу лет работы датчик выдаст повторяющееся значение, равно 10 ". Итак, можно сделать единственный вывод; управление идентификаторами типов не входит в когипетенцию фабрики объектов.

Поскольку язык С- -ь не может гарантировать уникальность и устойчивосп, илентификатора типов, управление ими выходит за рамки языка, и ответственность за его реализацию следует возложить на программиста. з Фабрика СОМ-объектов, разработанная компанией М!сгоюй, использует именно такой подход. Оиа содержит алгоритм, генерирующий уникальный !28-битовый идентификатор, называемый глобатьиым уникальным идентификатором (О!оьа! Опгяие 1депйбег — ОИО) СОМ- объектов.

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

Затем, обогатившись знаниями, вернемся к частному. 8.5. Обобщение Перечислим элементы, которые мы упомянули, обсуждая фабрики объектов. Это даст нам пишу лля размышлений при создании обобшенной фабрики объектов. ° Конкретное изделие (сопсгеге ргодцс1). Фабрика производит изделие в виде объекта. ° Абсглрактное изделие (аЬзсгасс ргос)цсс). Изделие создается на основе наследования базового типа (в нашем примере — класса зЬаре). Изделие — это обьект, тип которого принадлежит определенной иерархии.

Базовый тип этой иерархии представляет собой абстрактное изделие. Фабрика обладает полиморфным поведением, т.е. она возвращает указатель на абстрактное изделие, не передавая знания о типе конкретного изделия. ° Иденяификан~ар лшяа изделия (ргодцсг гуре )депбйег).

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

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

Характеристики

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6485
Авторов
на СтудИзбе
303
Средний доход
с одного платного файла
Обучение Подробнее