|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Учасники паттерна. 1. Component –компонент є абстракцією деякого елемента, для якого будуть визначені «декорації» (оформлення)1. Component – компонент є абстракцією деякого елемента, для якого будуть визначені «декорації» (оформлення). Звичайно ж, під «декоруванням» розуміється не візуальне оформлення, а додавання специфічних функцій: - визначає інтерфейс для об’єктів, на які можуть бути динамічно покладені додаткові обов’язки. 2. ConcreteComponent – конкретний компонент, його поведінку необхідно динамічно розширити, є субкласом класу Component: - визначає об’єкт, на який покладаються додаткові обов’язки. 3. Decorator – декоратор клас, що успадковує й агрегує компонент. Він перевизначає реалізацію операції таким чином, щоб виконати функцію, інкапсульовану в компоненті, а потім додати новий функціонал: - зберігає посилання на об’єкт Component та визначає інтерфейс, відповідний інтерфейсу Component. 4. ConcreteDecorator – конкретний декоратор: - містить змінну екземпляра, у якій зберігається об’єкт Component, що декорується; - може додавати нові методи, однак нова поведінка, зазвичай, додається до і після виклику існуючого методу класу Component; - покладає додаткові обов’язки на компонент.
Рис. 5.30. Діаграма класів паттерна Декоратор
Відносини учасників паттерна. Decorator переадресує запити об’єкту Component. Може виконувати і додаткові операції до і після пере адресації (рис. 5.31). Оскільки декоратор успадковує сomponent, то в якості інкапсульованого компонента може бути використаний інший декоратор, що дозволяє здійснювати рекурсивні послідовності викликів перевизначеної операції з поступовим «накопиченням» функціоналу (як показано на діаграмі послідовності рис. 5.31). ConcreteDecoratorA і ConcreteDecoratorB є реалізації декоратора для компонента. Два різних оформлення додаються шляхом простого вкладання одного декоратора в інший. Для досягнення цієї цілі кожен об’єкт-декоратор повинен дотримуватися інтерфейсу свого компонента і перенаправляти йому повідомлення.
Рис. 5.31. Діаграма послідовності для паттерна Декоратор
Особливості програмної реалізації. Застосування паттерну Декоратор вимагає розгляду кількох запитань: - відповідність інтерфейсів. Інтерфейс декоратора повинен відповідати інтерфейсу компонента, що декорується; - відсутність абстрактного класу Decorator. Немає необхідності визначати абстрактний клас Decorator, якщо планується додати лише один обов’язок. Так часто відбувається, коли працюєш зі вже існуючою ієрархією класів, а не створюєш нову. У такому разі відповідальність за переадресацію запитів, яку зазвичай несе клас Decorator, можна покласти безпосередньо на ConcreteDecorator; - полегшені класи Component. Щоб можна було гарантувати відповідність інтерфейсів, компоненти та декоратори повинні бути нащадками загального класу Component. Важливо, щоб цей клас був настільки легким, наскільки можливо. Результати використання. Використання паттерна володіє наступними особливостями: - декоратори мають той же супертип, що і об’єкти, які декоруються; - об’єкт можна «загорнути» в один або декілька декораторів; - оскільки декоратор відноситься до того ж супертипу, що і об’єкт, який декорується, можна передати декорований об’єкт замість вихідного; - декоратор додає свою поведінку до і (або) після делегування операцій декорованому об’єкту, що виконує іншу роботу; - об’єкт може бути декорований у будь-який момент часу, так що можна декорувати об’єкти динамічно і з довільною кількістю декораторів; - більша гнучкість, ніж у статичного спадкування. Паттерн Декоратор дозволяє більш гнучко додавати об’єкту нові обов’язки, ніж було б можливо у випадку статичного (множинного) спадкування. Декоратор може додавати і видаляти обов’язки під час виконання програми. При використанні ж спадкування потрібно створювати новий клас для кожного додаткового обов’язку, що веде до збільшення кількості класів і, як наслідок, до зростання складності системи. Декоратори дозволяють легко додати одну і ту ж властивість двічі; - дозволяє уникнути перевантажених функціями класів на верхніх рівнях ієрархії. Декоратор дозволяє додавати нові обов’язки по мірі необхідності. Замість того, щоб намагатися підтримати всі мислимі можливості в одному складному класі, який допускає різнобічне налаштування, можна визначити простий клас і поступово нарощувати функціональність за допомогою декораторів. Паттерн Адаптер, ще називають паттерном-обгорткою. І Адаптер і Декоратор – це паттерни, які можуть так називатися, але слід розрізняти їхнє призначення. Паттерн Адаптер застосовується для представлення одного під виглядом іншого, а Декоратор для додавання до існуючого більшої функціональності, хоча вони обоє агрегують певний об’єкт. Адаптер може змінити інтерфейс поведінки, а Декоратор – ні (вона унаслідується від компонента). Паттерн Заступник (Proxy) Призначення. Заступник – це структурний паттерн, який є сурогатом іншого об’єкта і контролює доступ до нього. Паттерн Proxy часто іменується як паттерн сурогат, обидва терміни є вірними й описують теж саме. Проксі – це деякий об’єкт, що забезпечує транзитний доступ до іншого об’єкта. Сурогат – це деякий об’єкт, що зовні нічим не відрізняється від основного, але внутрішньої функціональності в ньому немає. Об’єкт Сурогат або Проксі зовні нічим не відрізняється від об’єкта, що він представляє, але вся його внутрішня функціональність лише є деяким тунелем, через які класи клієнта одержують доступ до основних об’єктів. Так само об’єкт Сурогат або Проксі можна називати Заступником об’єкта [28]. Частота використання Мотивація застосування. Код одних програмістів повинний бути зрозумілий іншим програмістам, відносно як синтаксичних «традицій» так і структурних. Якщо будувати додаток, використовуючи паттерн Заступник для доступу до об’єктів, то в об’єктах-сурогатах буде міститися перевірка даних, а в самому цільовому класі виконуватися логіка. Потім досить легко буде пояснити іншому програмісту, де виконуються перевірки, а де основна логіка. Узагалі використовуючи паттерни досить легко пояснити структуру додатка. Напевно, приходилося бачити додатки, що після початку запуску, дуже довго «думають» і тільки після закінчення 5 або більш секунд починають відображати свій інтерфейс. Так виходить, тому що додаток відразу при старті починає завантажувати усі свої модулі, створює всі екземпляри класів, що знадобляться (або не знадобляться) у роботі додатка. Для часткового рішення такої проблеми, можна створити Заступника «важкого» об’єкта. Створювати такий об’єкт необхідно при старті додатка. Заступник – це лише муляж, який не є таким «важким» як цільовий об’єкт і тому створюється швидше, а «важкий» об’єкт буде створений тільки тоді, коли він буде дійсно необхідний. А необхідність з’являється, коли класи клієнта будуть працювати з об’єктом Заступника, який всі запити буде перенаправляти на тільки що створений цільовий об’єкт. Метою паттерну є створення системи доступу до об’єкта через спеціальний об’єкт сурогату (рис. 5.32).
Рис. 5.32. Схема доступу до цільового класу через заступника
Це дозволяє домогтися більшої гнучкості роботи з об’єктом цільового класу. Якщо об’єкт цільового класу після створення буде займати багато місця і немає гарантії того, що об’єкт буде необхідний у роботі додатка – можна створювати цільовий об’єкт тільки коли клієнт перший раз викликає метод з об’єкта-сурогату – це прискорить швидкодію додатка у випадку, якщо об’єкт не буде використовуватися. А якщо об’єкт і буде створений, то на етапі виконання програми це буде не так «болісно» для користувача. Така система доступу дозволить так само використовувати цільовий клас з більшим захистом (у сурогаті можна виконувати різні перевірки прийнятих параметрів). Наприклад, якщо цільовий клас – це калькулятор, просто приймає в аргументи методу два параметри і виконує базові математичні операції, у сурогаті класу калькулятор можна виконати перевірку, щоб не вийшло, що калькулятору буде передана задача, «поділити на нуль». Можливо використовувати структуру паттерна Заступник для створення так званого «Посла» в інший простір імен. Наприклад, цільовий клас описаний у просторі імен, що з якихось причин не можливо (або незручно) підключити, у такому випадку можна створити сурогат, що буде знаходитися в "потрібному" просторі імен, а всередині сурогату буде створений об’єкт цільового класу з іншого простору імен. Паттерн Заступник доцільно використовувати, коли: - об’єкт RealSubject працює на віддаленому комп’ютері; - якщо створення екземплярів RealSubject зв’язано з великими витратами; - якщо доступ до RealSubject повинний бути тим або іншим способом захищений. Різновиди Заступника [10]: - віддалений Заступник управляє доступом до віддаленого об’єкту. Надає локального представника замість об’єкта, що знаходиться в іншому адресному просторі. В цьому різновиді паттерна Заступник виконує функції локального представника об’єкта, що знаходиться на іншій віртуальній машині. Виклик метода заступника передається по мережі, метод викликається на віддаленому комп’ютері, результат повертається заступнику, а потім і клієнту (рис. 5.33.)
Рис. 5.33. Схема віддаленого заступника
- віртуальний заступник керує доступом до ресурсів, створення яких вимагає великих витрат ресурсів. Віртуальний Заступник надає об’єкт, створення якого вимагає великих витрат ресурсів. Створення об’єкта часто відкладається до моменту його безпосереднього використання. Віртуальний заступник також виконує функції сурогатного представника об’єкта до і під час його створення. В подальшому заступник делегує запити безпосередньо до RealSubject (рис. 5.34).
Рис. 5.34. Схема віртуального заступника - захисний Заступник контролює доступ до ресурсу у відповідності з системою привілеїв. Такі Заступники корисні, коли для різних об’єктів визначені різні права доступу. Є ще одна оптимізація, яку паттерн Заступник іноді приховує від клієнта. Вона називається копіюванням при записі (copy-on-write) і має багато спільного із створенням об’єкта на вимогу. Копіювання великого й складного об’єкта – дуже дорога операція. Якщо копія не модифікувалася, то немає сенсу платити цю ціну. Якщо відкласти процес копіювання, застосувавши заступник, то можна бути впевненим, що ця операція відбудеться тільки тоді, коли він дійсно був змінений. Щоб під час запису можна було копіювати, необхідно підраховувати посилання на суб’єкт. Копіювання Заступника просто збільшує лічильник посилань. І тільки тоді, коли клієнт запитує операцію, змінює суб’єкт, заступник дійсно виконує копіювання. Одночасно заступник повинен зменшити лічильник посилань. Коли лічильник посилань стає рівним нулю, суб’єкт знищується. Віртуальний Заступник – звичайний механізм додавання поведінки на час завантаження великого витратного об’єкта, а Віддалений Заступник – позбавлення клієнтів від низькорівневої взаємодії з віддаленими об’єктами. Розумно керувати доступом до об’єкту завдяки Захисному Заступнику, оскільки тоді можна відкласти витрати на створення і ініціалізацію до моменту, коли об’єкт дійсно знадобиться. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.005 сек.) |