|
Программирование >> Разработка устойчивых систем
Суррогатные объекты Паттерны Посредник (Proxy) и Состояние (State) основаны на применении суррогатных классов. Ваша программа взаимодействует с суррогатным классом, за которым скрывается настоящий класс, выполняющий реальную работу. При вызове функции суррогатный класс просто переадресует вызов соответствующей функции класса реализации. Эти два паттерна имеют так много общего, что со структурной точки зрения Посредник может считаться частным случаем Состояния. Возможно, вам даже захочется объединить их в новый паттерн Суррогат, но эти паттерны различаются по своему предназначению, то есть смысловому наполнению. Многие ошибочно полагают, что если два паттерна имеют сходную структуру, то и различать их не нужно. Чтобы понять, когда применяется тот или иной паттерн, всегда следует разобраться в его предназначении. Основная идея проста: суррогатный класс объявляется производным от базового класса. Вместе с ним от этого же базового класса порождаются другие классы, предоставляющие фактическую реализацию: Интерфейс
При создании суррогатного объекта задается реализация, которой будут передаваться вызовы функций. Со структурных позиций отличия между Посредником и Состоянием просты: Посредник имеет только одну реализацию, тогда как у Состояния их может быть несколько. Соответственно различаются и области применения этих паттернов (по БЧ): Посредник обеспечивает контроль за доступом к реализации, а Состояние позволяет динамически выбирать реализацию. Впрочем, если понимать смысл выражения управление доступом к реализации более широко, различия между этими паттернами стираются. мы - соответствующие вызовы находятся в конце процедур procedurel, procedure2 и procedures. Конечно, при реализации этого рещения приходится немного потрудиться. Но как будет показано в главе И, для предотвращения проблем, возникающих при многопоточном программировании, необходимо действовать крайне продуманно и внимательно, поэтому более простое решение может оказаться предпочтительным. Также можно организовать очень простую многопоточную схему, переместив вызовы TaskRunner::run() в отдельный программный поток таймера. В этом случае полностью устраняется всякая привязка обычных операций к коду обработки событий. Посредник Реализация Посредника для приведенной выше диаграммы выглядит так: / /: СЮ ProxyDemo. срр Простая демонстрация паттерна Посредник #1nclude <1ostream> using namespace std: class ProxyBase { public: virtual void f() = 0: virtual void g() = 0: virtual void h() = 0: virtual -ProxyBaseO {} class Implementation : public ProxyBase { public: void f() { cout Implementation.f() endl void g() ( cout Implementation.g() endl void hO { cout Implementation.hO endl class Proxy : public ProxyBase { ProxyBase* implementation: public: ProxyO { implementation = new ImplementationO: } -ProxyО { delete implementation: } Передача вызовов реализации: void fO { implementation->f(); void gO { implementation->g(): void h() { implementation->h(); int mainO Proxy p: p.fO: p.gO; p.hO: } /:- В некоторых случаях класс Implementation даже не обязан иметь одинаковый интерфейс с классом Proxy - если Proxy умеет взаимодействовать с классом Implementation и передавать ему вызовы функции, основной принцип успешно работает (обратите внимание: данное утверждение противоречит определению Посредника по БЧ). Тем не менее, наличие общего интерфейса позволяет произвести прямую замену исходного объекта объектом Посредника в клиентском коде: клиентский код написан для взаимодействия с исходным объектом, и его не придется изменять для работы с Посредником (вероятно, это один из важнейших аспектов применения Посредника). Кроме того, наличие общего интерфейса гарантирует, что Implementation содержит все функции, вызываемые Proxy. Различия между Посредником и Состоянием определяются кругом задач, решаемых при помощи этих паттернов. Основные области применениями Посредника перечислены далее (по БЧ). Удаленный посредник. Посредник представляет объект, находящийся в другом адресном пространстве (в реализации используются удаленные объектные технологии). Виртуальный посредник. Обеспечивает отложенную инициализацию, чтобы дорогостоящие операции создания объектов выполнялись по мере необходимости. Защитный посредник. Применяется в тех случаях, когда вы не хотите предоставлять прикладному программисту полный доступ к объекту реализации. Умные ссылки. Выполнение дополнительных действий при обращении к объекту реализации. Примером служит подсчет ссылок, то есть отслеживание количества ссылок на объект (используется в реализации идиомы копирования при записи). Более простой пример - подсчет вызовов определенной функции. Состояние Объект, созданный с применением паттерна Состояние, словно меняет свой класс в процессе работы. Если многие или все функции класса содержат условный код, стоит подумать о применении этого паттерна. Как и в случае с Посредником, интерфейсный объект использует служебный объект реализации для выполнения своих функций. Однако паттерн Состояние позволяет переключаться на другие реализации в течение жизненного цикла интерфейсного объекта, а, следовательно, - изменять поведение объекта при одних и тех же вызовах функций. Такой подход позволяет улзщить структуру кода в тех случаях, когда вы проверяете в каждой функции несколько условий и по результатам проверки решаете, что нужно делать в этой функции. Возьмем классический сюжет о царевне-лягушке: имеется объект (существо), которое по-разному ведет себя в зависимости от текущего состояния. Очевидно, действие можно выбрать в зависимости от состояния логического флага: : C10:KissingPrincess.cpp #1 nclude <iostream> using namespace std: class Creature { bool isFrog: public: CreatureO : isFrog(true) {} void greet0 { if(isFrog) cout Ribbet! endl: else cout Darling! endl: void kissO { isFrog = false: } int mainO { Creature creature: creature.greetO: creature.kissO: creature.greetO: } /:-
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |