Міністерство освіти та науки України
Національний університет “Львівська Політехніка”
Кафедра ІСМ
ЗВІТ ПРО ВИКОНАННЯ РОЗРАХУНКОВОЇ РОБОТИ
з курсу “Технології проектування програмних систем”
на тему: «Технологія аспектно-орієнтованого проектування»
Національний університет “Львівська Політехніка”
Кафедра ІСМ
Дисципліна “ Технології проектування програмних систем ”
Курс IV Група КН-419 Семестр 7
Завдання на розрахункову роботу студента Рудого Я. М.
Тема роботи: “Технологія аспектно-орієнтованого проектування”
Завдання:
Виконати огляд літератури та джерел Internet за заданою темою.
Якщо не задано, то вибрати необхідні інструментальні та бібліотечні засоби для проектування.
Розробити та реалізувати контрольний приклад.
Оформити звіт по виконаній роботі.
Дата видачі: 16.11.2006
Підпис студента:
Підпис викладача:
Зміст
Вступ 4
1. Роботи в області аспектно-орієнтованого програмування 5
2. Існуючі підходи до розробки програмних систем 6
2. 1. Еволюція методологій розробки ПЗ 6
2. 2. Система як набір функціональних вимог 6
2. 3. Наскрізна функціональність в системі 8
3. Введення в АОП 11
3. 1. Основні концепції АОП 11
3. 2. Переваги використання АОП 14
3. 3. Недоліки аспектного підходу 16
3. 4. ASPECTJ як одна з реалізацій АОП 18
3. 5. Інші реалізації АОП 22
Висновки 22
Список літератури 23
Вступ
Об'єктно-орієнтоване програмування (ООП) було представлене як технологія, що сприяє процесу проектування ПО, оскільки об'єктна модель краще вписується в реальну наочну область і може бути представленна наочно. Але виявлено безліч проблем в реалізації систем, де ООП не достатньо для чіткої фіксації важливих архітектурних рішень програми. Існують деякі проблеми, для яких не підходять ні об'єктноорієнтовані (ООП) ні процедурноорієнтовані мови програмування (ПІП).
Аспектно-орієнтоване програмування (АОП) дозволяє чітко виразити код, залучений в аспект, включаючи відповідну ізоляцію, композицію, і повторне використання. Не дивлячись на те, що АОП і є новою ідеєю, існують інші системи, що мають схожі властивості.
Аспектно-орієнтоване програмування (АОП) є однією з концепцій програмування, яка є подальшим розвитком процедурного і об'єктно-орієнтованого програмування (ООП). Дана методологія покликана понизити час, вартість і складність розробки сучасного ПО, в якому, як прищепило, можна виділити певні частини, або аспекти, що відповідають за ту або іншу функціональність, реалізація якої розосереджена за кодом програми, але складається з схожих шматків коду. По оцінках фахівців, близько 70% часу в проектах витрачається на супровід і внесення змін в готовий програмний код. Тому достатньо важливою в найближчій перспективі стає роль АОП і подібних трансформаційних підходів. Порівняно нова технологія вже набула досить широкого поширення показавши свою ефективність на тестових застосуваннях, проте місце цього підходу в індустрії ПО по ряду об'єктивних причин все ще не визначено.
Істотна межа програмної системи — рівень складності: один розробник практично не в змозі охопити всі деталі системи, причому складність властива більшості сучасних програмних систем. Дана складність неминуча: з нею можна справитися, але позбавитися від неї не можна. Складність програмних систем обумовлена чотирма основними причинами: складністю реальної наочної області, з якої виходить замовлення на розробку; трудністю управління процесом розробки; необхідністю забезпечити достатню гнучкість програми; незадовільними способами опису поведінки великих дискретних систем.
Об'єктом дослідження даної роботи є аспектно-орієнтований підхід при розробці програмних систем. АОП пропонує мовні засоби, що дозволяють виділяти крізну функціональність в окремі модулі, і таким чином спрощувати роботу (відладку, модифікацію, документування і т.д.) з компонентами програмної системи, і знижувати складність системи в цілому. Тут і далі під "модулем" розуміється деяка чітко виражена структурна одиниця програми — процедура, функція, метод, клас або пакет. Програмний модуль в термінах деякої даної парадигми програмування (наприклад, ООП) назвемо компонентом.
Мета дослідження полягає в аналізі можливих варіантів застосування нового підходу при вирішенні проблеми складності програмних продуктів, що росте, на різних етапах життєвого циклу, порівняння реалізацій запропонованих варіантів з традиційною об'єктно-орієнтованою реалізацією, а також прогляданні подальших перспектив в розвитку нової методології.
Для вирішення поставленого завдання, необхідно здійснити аналіз існуючих підходів при розробці програмних систем, описати проблеми які з'являються при використанні функціональної декомпозиції за наявності крізних системних вимог, зробити огляд аспектної методології і інструментів тих, що підтримують її. Ввести критерії порівняння ОО і АТ реалізацій, а також представити варіанти застосування аспектно-орієнтованого підходу на прикладах. Для кожного прикладу приведена реалізація на мові Java, її аспектно-орієнтований аналог і їх порівняльний аналіз.
Поява нових парадигм програмування завжди була цікавою темою, оскільки кожна нова методологія розробки програмного забезпечення дозволяла вирішувати проблеми, що є посилками для її появи, і значно просувала науку Computer Science і індустрію ПО в цілому. Ускладнення програмних систем — як глобальна проблема вимагає постійної уваги і вивчення, тому поява АОП представляється широким полем для досліджень з подальшим їх практичним застосуванням.
У роботі пропонуються шляхи використання аспектного підходу на різних етапах життєвого циклу ПО. Крім того, в роботі приводиться опис АОП, дається огляд існуючих підходів при розробці програмних систем і робиться спроба локалізації переваг і, головне, недоліків нової методології.
1.Роботи в області аспектно-орієнтованого програмування
Основні ідеї АОП були сформульовані найбільш явній формі в одній з ранніх статей ідеологом методології Грегором Кикжалесом (Gregor Kiczales). На сервері підтримки і розвитку АОП можна отримати актуальну інформацію про розвиток даної методології, а також дізнатися про події і конференція тих, що проходять з цієї тематики. Хороший огляд по АОП представлений в дисертації .
АОП — методологія, в основі якої лежать ідеї, що зустрічаються в області технології програмування вже достатньо давно. Це суб'єктний-орієнтоване програмування (subject-oriented programming) , композиційні фільтри (composition filters), адаптивне програмування (adaptive programming). АОП тісно пов'язано з ментальним програмуванням (intentional programming), концепції якого викладені в роботі Чарльза Саймоні. Іншою близькою ідеологією є те, що так зване породжує, або трансформаційне, програмування (generative programming, transformational programming) .
У [2] автори пропонують коротке введення в проблематику АОП, представлені ключові поняття АОП і розглянуті способи інтеграції аспектів, у тому числі і на етапі виконання програми. У [3] наголошуються переваги АОП-підходу, недоліки існуючих реалізацій опису точок скріплення аспектів і функціональних модулів. Запропонована модифікація моделі ASPECTJ для завдання точок скріплення аспектів.
У статті [21] автор дає основні поняття АОП, вводить термін крізна функціональність, а також надає короткий опис мови ASPECTJ.
Оскільки всі приклади розроблялися з використанням найбільш популярної реалізації ASPECTJ, то основна література, що вивчається по реалізаціях АОП, — це література що стосується цієї мови. Керівництво користувача [17] є основним документом, що описує дане розширення мови Java. У [4] автор детально розглядає мову ASPECTJ, ця книга використовувалася як альтернативне джерело інформації. Крім того, з джерела [22] можна отримати інформацію про всі підтримувані на даний момент розширення мов і інші інструменти підтримуючих АОП. Наприклад, в статті [19] описаний зв'язок між АОП і .NET
У класичній праці [6] описуються прості і витончені рішення типових завдань, що виникають в об'єктно-орієнтованому проектуванні. Автори висловлюють принципи використання шаблонів проектування і приводять їх каталог. У [7] описані ефективні методи застосування всіх типів шаблонів проектування стосовно платформи Java. У [5] і [13] автори показують застосовність аспектного підходу для реалізації протоколу взаємодії об'єктів при реалізації шаблонів проектування. У цих роботах вони розглядають поліпшення в термінах модульної, підвищення ступеня повторного використання і покращуваного сприйняття початкового коду класів учасників шаблонів з каталога [6].
У [11] дається поняття "Контрактного проектування" (Design by Contract) — техніка сприяючою створенню надійного об'єктно-орієнтованого програмного забезпечення. У [12] розглядаються загальні підходи при обробці помилок на етапі розробки ПО, даються поради по використанню АОП і робляться виводи про застосовність нового підходу на даному етапі життєвого циклу.
2.Існуючі підходи до розробки програмних систем
2.1.Еволюція методологій розробки ПЗ
На початку ери обчислювальної техніки програми розроблялися за допомогою прямого кодування на машинній мові. Програмісти витрачали велику кількість часу, роздумуючи над особливостями використання того або іншого набору машинних інструкцій, чим безпосередньо над завданням, що стоїть перед ними. Потім перешли до мов більш високого рівня, які дозволяли абстрагуватися від машинного рівня. Потім прийшла ера структурованих мов, тепер програмісти могли проводити структурну декомпозицію проблем в термінах процедур, необхідних для виконання того або іншого завдання. Проте, із зростанням складності програмного забезпечення виникла потреба в іншій технології. Об'єктно-орієнтоване програмування дозволило представити систему як безліч взаємодіючих об'єктів. Класи дозволили приховати деталі реалізації за інтерфейсами. Механізм поліморфізму забезпечив загальну поведінку і інтерфейс зв'язаних концепцій і дозволив управляти поведінкою компонентів без доступу до реалізації базових концепцій.
Методології розробки ПО і мови програмування визначили шлях взаємодії людини з комп'ютером. Кожна нова методологія представляє нові шляхи декомпозиції проблем: машинний код, машинно-незалежний код, процедури, класи і т.д. Кожна нова методологія дозволяла все більш природно відобразити вимоги до продукту на програмні конструкції. Еволюція програмних методологій дозволила створювати складніші системи.
В даний час об'єктно-орієнтоване програмування (ООП) є методологією, на користь якої робиться вибір більшістю нових проектів розробки програмних продуктів. Поза сумнівом, методологія ООП продемонструвала свою силу при моделюванні загальної поведінки системи, що розроблялася. Проте, як можна переконатися з досвіду, ООП не в достатній мірі дозволяє справлятися з складністю програмних систем, що росте.
2.2.Система як набір функціональних вимог
Як правило, будь-яка програмна система складається з декількох частин: основній (наочно-орієнтованою) і системній частині, які несуть в собі необхідну функціональність. Наприклад, ядро системи обробки кредитних карт призначене для роботи з платежами, тоді як функціональність системного рівня призначена для ведення журналу подій, цілісності транзакцій, авторизації, безпеки, продуктивності і т.д. Більшість подібних частин системи, відомі як крізна функціональність [2], зачіпають безліч основних наочно-орієнтованих модулів. Можна розглядати складну програмну систему як комбінацію модулів, кожен з яких включає окрім бизнес-логики частина крізної функціональності з набору вимог до системи. Малюнок 1 показує систему як набір таких вимог розбитих на різні модулі.
Малюнок 1. Система як набір функціональних модулів.
При розробці програмної системи з використанням існуючих методологій програмування крізна функціональність буде включена у всі модулі, в результаті система буде складною при проектуванні, розумінні, реалізації і підтримці.
Малюнок 2 представляє набір вимог як світловий промінь, що проходить через призму. Після проходження світивши через призму здатну розділяти вимоги, вимоги розкладаються в спектр по функціональності.
Малюнок 2. Декомпозиція вимог: виділення функціональності.
Розробник створює програмну систему як результат обробки безлічі вимог. Можна явно виділити з цієї безлічі вимоги до логіки конкретного модуля і загальносистемні вимоги. Багато хто з системних вимог може бути ортогональним один одному і вимогам конкретного модуля. Вимоги системного рівня мають тенденцію перетинатися з безліччю основних вимог. Наприклад, типова система рівня підприємства включає такі види крізної функціональності як аутентифікація, ведення журналу подій, управління ресурсним пулом, адміністрування, аналіз продуктивності і управління носіями інформації. Кожна з цих вимог до системи зачіпає безліч підсистем, наприклад, вимога по управлінню носіями інформації зачіпає кожен бізнес-об'єкт, що зберігається.
Сучасні технології розробки ПО на рівні мов програмування надають зручні засоби для виділення логіки функціонування програми в окремі модулі, але не одна з них не пропонує зручного способу локалізації в окремі модулі функціональності, яка повинна розповсюджуватися на всю систему.
Через те, що реалізація крізної функціональності не може бути відособлена засобами мови програмування в окремому програмному модулі, елементи цієї реалізації присутні в тому або іншому вигляді в більшості модулів, створюючих програмну систему. Розглянемо приклад java-класу, основним завданням якого є реалізація деякої логіки:
public class SomeBusinessClass {
// Бізнес-дані
// допоміжні дані
public void performSomeOperation(OperationInformation info){
// перевірити рівень доступу даним
// перевірити відповідність вхідних даних контракту
// заборонити доступ даним іншим потокам виконання
// перевірити стан кеша даних
// занести в журнал відмітку про початок операції
// ==== Реалізація логіки даного класу ====
// занести в журнал відмітку про кінець операції
// вирішити доступ даним іншим потокам виконання
}
}
В даному прикладі можна виділити дві проблеми. По-перше, визначувані допоміжні дані не відносяться до вимог, що накладаються на даний модуль, а потрібні для роботи крізної функціональності. По-друге, реалізація performSomeOperation(..) виглядає більш навантаженою, ніж просто "Реалізація логіки даного класу". Для правильної роботи даного методу по вимогах необхідно виконати ряд дій, що не відносяться конкретно до даного модуля, — перевірити рівень доступу даним, перевірити відповідність вхідних даних контракту, заборонити доступ даним іншим потокам виконання, перевірити стан кеша даних, занести в журнал відмітку — це вимоги системного рівня. До того ж, багато хто з цих загальних вимог повинен бути реалізований в інших модулях.
На малюнку 3 схемний зображений розподіл функціональності "ведення журналу подій" по модулях деякої програмної системи. У кожному модулі відмічений код, що реалізовує вимогу "ведення журналу подій".
Малюнок 3.
Ведення журналу подій — типовий приклад крізної функціональності, аспекту функціонування системи, реалізація якого присутня в багатьох програмних модулях. При аналізі вимог до системи можна виділити і інші аспекти функціонування подібного типу. Дані аспекти функціонування системи об'єднує те, що їх реалізація не може бути локалізована наявними засобами мови програмування в окремому програмному модулі (або ряду модулів). Схемний розподіл функціональності "ведення журналу подій" в програмній системі в деякому "ідеальному" варіанті представлене на малюнку 4.
Малюнок 4.
2.3.Наскрізна функціональність в системі
Не дивлячись на те, що крізна функціональність може пронизувати велику кількість модулів, існуючі технології мають тенденцію реалізувати ці вимоги, використовуючи одновимірні підходи, направляючи всі зусилля по реалізації вимог уздовж одного вимірювання. Це єдине вимірювання якраз є реалізацією вимог що відносяться до модулів. Вимоги, що залишилися, лягають уздовж цього головного вимірювання. Іншими словами, весь простір вимог є n-мірним, тоді як простір реалізації представляється одновимірним простором. В результаті отримуємо важко підтримуване відображення вимог в реалізацію.
Малюнок 5.
Ознаки.
Декілька ознак, які можуть указувати на проблемну реалізацію крізної функціональності при використанні існуючих підходів. Розіб'ємо ці ознаки на дві категорії:
Заплутаний код: У модулі може бути реалізовані декілька вимог. Наприклад, часто розробники одночасно вирішують проблеми пов'язані з бізнес логікою, продуктивністю, синхронізацією потоків і безпекою. В результаті безліч елементів з різних вимог присутня в модулі, що розробляється, що приводить до заплутаного коду.
Розосереджений код: Оскільки крізна функціональність за визначенням розповсюджується на безліч модулів, то виклики цієї функціональності будуть розосереджені по всій системі. Наприклад, якщо в системі використовується вимога по стеженню за продуктивністю роботи бази даних, то така крізна функціональність торкнеться всіх модулів, що працюють з базою даних.
Наслідки.
Наявність заплутаного і розосередженого коду впливають на проектування і реалізацію у багатьох відношеннях:
Погане дослідження призначення модуля: Одночасна реалізація декількох вимог в одній модульній одиниці робить неясною відповідність між окремою вимогою і його реалізацією, в результаті скрутного зрозуміти, що реалізує конкретний модуль.
Непридатність коду для повторного використання: У зв'язку з тим, що модуль може використовувати в собі деяку крізну функціональність з жорсткою прив'язкою до цієї функціональності, інші частини системи або інші проекти, де може потрібно вже написаний модуль (але з іншими вимогами до крізної функціональності) не можуть використовувати вже написаний модуль.
Велика вірогідність помилок: Заплутаність коду спричиняє за собою код з безліччю прихованих проблем. Більш того, реалізація декількох ортогональних вимог в одному модулі може привести до того що жодне з них не отримає достатньої уваги розробника.
Складність в супроводі: Поява додаткових вимог в майбутньому зажадає переробки поточної реалізації, і це може торкнутися більшості існуючих модулів. Модифікація кожної окремої підсистеми окремо під нові вимоги може привести до несумісності.
З тих пір, як складність програмних систем зросла і з'явилася крізна функціональність, що знаходиться на зрізі системи, не дивно, що з'явилися декілька підходів для вирішення цих проблем. Ці підходи включають класи-домішки (mix-in) [20], шаблони проектування [6] і специфічні доменні рішення.
При використанні класів-домішок реалізацію крізної функціональності можна помістити в них. Компоненти містять екземпляр класу mix-In і дозволяють іншим частинам системи встановлювати свій екземпляр.
Поведінкові шаблони проектування, такі як Visitor або Template Method дозволяють помістити крізну функціональність в головні класи, які як у разі mix-In класів обходитимуть компоненти, при цьому викликаючи логіку специфічну для відвідин даного компоненту або викликаючи специфічний шаблонний метод.
Специфічні доменні рішення, такі як, наприклад, каркаси (framework) і сервера застосувань, дозволяють розробникам виносити деякі крізні вимоги на рівень цих рішень. Наприклад, архітектура EJB дозволяє винести на рівень сервера застосування крізну функціональність наступного вигляду — безпека, адміністрування, аналіз продуктивності і управління поведінкою перманентних об'єктів, і сфокусуватися тільки на розробці компонентів рівня підприємства. Специфічні доменні рішення пропонують спеціалізований механізм для вирішення специфічних проблем, проте при зміні технології доводиться наново вивчати нові підходи для вирішення тих же проблем.
Перед системним архітектором при проектуванні системи виникає дилема по вибору технології при реалізації крізних вимог — або скористатися одним з рішень конкретної проблеми, що існують на даний момент, або скористатися новою технологією покликаною вирішувати подібні проблеми.
3.Введення в АОП
АСПЕКТ (від латів. aspectus — вигляд), точка зору, з якою розглядається яке-небудь явище, поняття, перспектива. (Великий енциклопедичний словник)
Дослідники вивчили різні шляхи виділення в окремі модулі крізної функціональності в складних програмних системах. Аспектно-орієнтоване програмування (АОП) є одним з цих рішень. АОП пропонує засоби виділення крізній функціональності в окремі програмні модулі — аспекти.
З погляду АОП в процесі розробки достатньо складної системи програміст вирішує дві ортогональні задачі:
Розробка компонентів, тобто виявлення класів і об'єктів, складових словник наочної області.
Розробка сервісів, що підтримують взаємодію компонентів, тобто побудова структур, що забезпечують взаємодію об'єктів, при якій виконуються вимоги завдання.
Сучасні мови програмування (такі як, наприклад, C++, VB і т.п.) орієнтовані, перш за все, на рішення першої задачі. Код компоненту представляється у вигляді класу, тобто він добре локалізований і, отже, його легко проглядати, вивчати, модифікувати, повторно використовувати. З іншого боку, при програмуванні процесів, в які залучені різні об'єкти, ми отримуємо код, в якому елементи, пов'язані з підтримкою такого процесу, розподілені за кодом всієї системи. Ці елементи зустрічаються в коді безлічі класів, їх сукупність в цілому не локалізована в осяжному сегменті коду. В результаті ми стикаємося з проблемою "заплутаного" коду.
В рамках АОП затверджується, що ніяка технологія проектування не допоможе вирішити дану проблему, якщо тільки ми залишатимемося в рамках мови, орієнтованої тільки на розробку компонентів. Для програмування сервісів, що забезпечують взаємодію об'єктів, потрібні спеціальні засоби, можливо спеціальні мови. Після етапу кодування компонентів і аспектів на відповідних мовах виконується автоматична побудова оптимізованого для виконання (але не для перегляду і модифікації) коду. Цей фінальний процес називається злиттям або інтеграцією (weaving).
3.1.Основні концепції АОП
Аспектно-орієнтований підхід розглядає програмну систему як набір модулів, кожен з яких відображає певний аспект — мету, особливість функціонування системи. Набір модулів, створюючих програму, залежить від вимог до програми, особливостей її наочної області. Разом з функціональними вимогами до програми пред'являються і загальносистемні вимоги, наприклад: цілісності транзакцій, авторизованого доступу до даним, ведення журналу подій і т.д. При проектуванні програмної системи розробник вибирає модулі так, щоб кожен з них реалізовував певну функціональну вимогу до системи. Проте реалізація деяких вимог до програми часто не може бути локалізована в окремому модулі в рамках процедурного або об'єктно-орієнтованого підходу. В результаті код, що відображає такі аспекти функціонування системи, зустрічатиметься в декількох різних модулях. Традиційні парадигми програмування використовують при проектуванні програми функціональну декомпозицію і не дозволяють локалізувати крізну функціональність в окремих модулях. Необхідність реалізації крізної функціональності наявними засобами веде до того, що деякий компонент містить код, що відображає безліч ортогональних вимог до системи. Це робить такий модуль вузькоспеціалізованим, погіршує можливості його повторного використання і в деяких випадках приводить до дублювання коду. У свою чергу, це викликає підвищення вірогідності внесення помилок, збільшення часу відладки, знижує якість програми і у великій мірі утрудняє її супровід. Аспектно-орієнтований підхід в деяких випадках дозволяє уникнути описаних проблем і поліпшити загальний дизайн системи, забезпечуючи можливість локалізації крізної функціональності в спеціальних модулях — аспектах.
АОП дозволяє реалізовувати окремі концепції в слабосвязанном вигляді, і, комбінуючи такі реалізації, формує кінцеву систему. АОП дозволяє побудувати систему, використовуючи слабосвязанные розбиті на окремі модулі (аспекти) реалізації загальносистемних вимог.
Розробка в рамках АОП складається з трьох окремих кроків:
Аспектна декомпозиція: розбиття вимог для виділення загальній і крізній функціональності. На цьому кроці необхідно виділити функціональність для модульного рівня з крізної функціональності системного рівня. Наприклад, в прикладі з кредитними картами можна виділити три речі: ядро обробки кредитних карт, журнал подій, аутентифікація.
Реалізація функціональності: Реалізувати кожну вимогу окремо. У прикладі з кредитними картами необхідно окремо реалізувати модуль обробки кредитних карт, модуль журналу, модуль аутентифікації.
Компоновка аспектів: На цьому кроці аспектний інтегратор визначає правила для створення своїх модулів — аспектів, складаючи кінцеву систему. У прикладі з кредитними картами необхідно визначити, в термінах мови реалізовуючого АОП, при виклику яких операцій необхідно вносити запис до журналу, і по завершенню яких дій необхідно повідомляти про успіх/неуспіх операції. Також можна визначити правила, по яких викликатиметься модуль аутентифікації перед доступом до бизнес-логике обробки кредитних карт.
Малюнок 6. Фази аспектно-орієнтованої розробки ПО.
АОП відрізняє багато що від традиційних підходів ООП при реалізації крізної функціональності: тут потрібно по-іншому уявляти собі процес декомпозиції, а архітектура програмного продукту, що виходить, в значній мірі виходить за рамки уявлень, традиційних для об'єктного програмування. При розробці на АОП концепції реалізуються абсолютно незалежно один від одного, оскільки всі зв'язки (крізна функціональність), що існують між ними, можуть бути локалізовані в аспектних модулях, що описують протокол взаємодії концепцій. Наприклад, в модулі обробки кредитних карт може бути відсутнім запис в журнал або виклик модуля авторизації, проте при роботі може викликатися подібна крізна функціональність, якщо вона описана в протоколі взаємодії. Це серйозний крок в розвитку методологій від ООП.
Аспектом в АОП є системний модуль, в який винесена крізна функціональність. Аспектний модуль — це результат аспектної декомпозиції, на етапі якої виявляються які-небудь явища, поняття, події які можуть бути застосовані до групи компонентів, отриманих після об'єктної декомпозиції. Аспект є мовною концепцією, схожою з класом, але тільки більш високого рівня абстракції.
Аспекти можуть зачіпати багато компонентів і використовують так звані точки вставки для реалізації регулярних дій, які зазвичай розосереджені по всьому тексту програми. У аспектному модулі описуються зрізи крапок — точки виконання програми, в які вбудовуються інструкції мови, які повинні виконуватися до, після або замість строго певної точки виконання програми. Подібні інструкції мови є функціональністю, що підтримує взаємодію компонентів. Крім того, в аспектному модулі можуть описуватися ролі компонентів, на які може впливати даний аспект. У окремих реалізаціях АОП за допомогою аспектних модулів можна впливати на існуючу схему спадкоємства. З погляду АОП аспект є сервісом, що зв'язує компоненти системи.
Приклад інтеграції аспектів.
Для ілюстрації роботи інтегратора аспектів повернемося наприклад обробки кредитних карт. Скорочено розглянемо тільки 2 операції — кредит і дебет:
public classCreditCardProcessor {
public void debit(CreditCard card, Currency amount)
throwsInvalidCardException, NotEnoughAmountException
CardExpiredException {
// логіка по дебету
}
public void credit(CreditCard card, Currency amount)
throws InvalidCardException {
// логіка по кредиту
}
}
і інтерфейс журналу подій:
public interface Logger {
public void log(Stringmessage);
}
Для отримання бажаної композиції потрібне застосування наступних правил, виражених на звичайній мові:
записати в журнал початок кожної операції
записати в журнал закінчення кожної операції
записати в журнал кожну виняткову ситуацію, яка може виникнути в процесі роботи цього модуля.
Інтегратор аспектів, застосовуючи такі правила, отримає код еквівалентний даному:
public class CreditCardProcessorWithLogging {
Logger _logger;
public void debit(CreditCard card, Money amount)
throws InvalidCardException, NotEnoughAmountException
CardExpiredException {
_logger.log("Starting CreditCardProcessor.debit(CreditCard
Money) "+ "Card: " + card + " Amount: " + amount);
// Debiting logic
_logger.log("Completing CreditCardProcessor.debit(CreditCard
Money) " + "Card: " + card + " Amount: " + amount);
}
public void credit(CreditCard card, Money amount)
throws InvalidCardException {
System.out.println("Debiting");
_logger.log("Starting CreditCardProcessor.credit(CreditCard
Money) " + "Card: " + card + " Amount: " + amount);
// Crediting logic
_logger.log("Completing CreditCardProcessor.credit(CreditCard
Money) " + "Card: " + card + " Amount: " + amount);
}
}
Автоматична компоновка аспектів і традиційних модулів програми — компонентів є ключовою властивістю АОП, яка визначає основну перевагу даної технології: робить можливою інкапсуляцію крізної функціональності в окремих програмних модулях.
Малюнок 7. Процес компоновки аспектних і традиційних модулів.
Автоматизована компоновка аспектів і компонентів є могутнім засобом генерації коду і в загальному випадку гарантує, що аспект буде застосований до всіх модулів-компонентів, які він зачіпає, чого складно добитися, якщо вносити крізну функціональність до модулів (уручну). Реалізація автоматичної компоновки аспектів і компонентів багато в чому визначає можливості тієї або іншої аспектно-орієнтованої платформи. В даний час обговорюються два підходи до інтеграції аспектів:
Статична інтеграція на етапі компіляції
Динамічна інтеграція на етапі виконання програми
Підходи до інтеграції аспектів визначаються мовою, підтримуючим АОП, і детально викладені в [2] .
3.2.Переваги використання АОП
АОП допомагає уникнути вищезазначених проблем, викликаних заплутаним і розосередженим кодом. Нижче представлені додаткові переваги АОП, що надаються:
Поліпшення декомпозиції системи на окремі модулі: АОП дозволяє інкапсулювати функціональність, яка не може бути представлена у вигляді окремої процедури або компоненту. АОП дозволяє реалізувати кожну вимогу окремо з мінімальним скріпленням, в результаті виходить модуль, що містить дану вимогу до системи без зовнішніх зайвих залежностей, навіть якщо це вимога — крізна функціональність. При такій реалізації модулі містять мінімальну кількість дубльованого коду. Оскільки кожна вимога реалізується окремо, це дозволяє уникнути заплутаного коду. В результаті виходить система, яку легко розуміти і підтримувати.
Спрощення супроводу програмної системи і внесення до неї змін: Оскільки можуть існувати модулі, на які можуть впливати аспекти, стає досить легко додавати нову функціональність шляхом створення нових аспектів. Більш того, якщо додається новий модуль в систему, то існуючі аспекти починають впливати і на нього без додаткових зусиль. При використанні АОП системний архітектор може відкласти рішення, що стосуються потенційно можливих вимог, оскільки згодом ці рішення зможуть бути реалізовані як окремі аспекти, що не торкнеться існуючої функціональності.
Поява можливостей повторного використання коду, що реалізовує крізну функціональність: Виходить з того, що при використанні АОП крізна функціональність може бути реалізована у вигляді аспектів і у вигляді слабосвязанных модулів.
Технологія винесення крізної функціональності в окремі аспектні модулі стала важливим еволюційним кроком в розвитку таких концепцій як абстракція і повторне використання програмного коду. Ідеї абстракції і повторного використання коду займають одне з центральних місць в програмуванні.
Абстракція — це метод, за допомогою якого розробники вирішувати складні проблеми, послідовно розбиваючи їх на простіші. Потім можна використовувати наявні готові рішення отриманих типових простих проблем як будівельні блоки, з яких розробники отримують рішення, придатні для реалізації повсякденних складних проектів [7] .
Повторне використання не менш важливий для розробки ПО, оскільки цей чинник є метою, до якої спрямована технологія розробки за своєю природою [7]. В процесі еволюції методологій розробки ПО було придумано декілька методів повторного використання коду і концепцій розробки ПО:
Раніше інших з'явився метод повторного використання, заснований на технології "скопіюй і встав", або, простіше кажучи, на вставці в нові програми фрагментів раніше створених програм. Даний підхід є абсолютно неефективним, крім того, він не дає ніяких скільки-небудь помітних якісних переваг з погляду абстракції коду.
Гнучкіший метод повторного використання полягає в повторному використанні алгоритмів. Відповідно до цього методу, розробник може використовувати будь-який одного разу розроблений алгоритм.
Функціональне повторне використання програмного коду і повторне використання структур даних дозволяють забезпечити безпосереднє повторне використання абстракції коду.
Двома розширеннями концепції повторного використання коду є бібліотеки функцій і API. Вони представляють розробникові отримати повний пакет функціональності, доступний для всіх подальших застосувань без необхідності копіювання програмного коду із застосування в застосування [7].
В ході розвитку об'єктно-орієнтованих мов програмування був здійснений величезний стрибок вперед в області абстракції і повторного використання програмного коду. За допомогою ООП була створена ціла плеяда високопродуктивних методів його створення. Проте зростання складності програмних систем привело до того, що з'явилася необхідність в повторному використанні крізної функціональності. Тому з'явилася потреба в новому підході повторного використання коду, який би охопив цей тип функціональності і вирішив би проблеми, які не могли вирішити попередні підходи.
Для ілюстрації важливості повторного використання коду в таблиці 1 приведена порівняльна характеристика з [7] різних підходів до повторного використання.
Метод
Повторне використання
Абстракція
Універсальність підходу
Копіювання і вставка
Дуже погано
Відсутній
Дуже погано
Структури даних
Добре
Тип даних
Середньо — добре
Функціональність
Добре
Метод
Середньо — добре
Типові блоки коду
Добре
Що типізується
Добре
Алгоритми
Добре
Формула
Добре
Класи
Добре
Дані + Метод
Добре
Бібліотеки
Добре
Функції
Добре — дуже добре
API
Добре
Класи утиліт
Добре — дуже добре
Компоненти
Добре
Групи класів
Добре — дуже добре
Шаблони проектування
Відмінно
Вирішення проблем
Дуже добре
Крізна функціональність
Середньо — добре
Відсутній
Погано
Крізна функціональність
Добре
Аспект
Дуже добре
У стовпці "Абстракція" даної таблиці вказана суть, для якої виконується абстракція, а в стовпці "Універсальність підходу" показано те, наскільки легко застосувати існуючий метод, не удаючись до змін або переробки коду. Показник ступеня повторного використання дуже сильно залежить від ефективності застосування того або іншого методу на практиці.
Можна сказати що, слабосвязанная реалізація крізної функціональності — це ключ до реального повторного використання коду. АОП дозволяє отримати менш зв'язану реалізацію, чим ООП. При використанні цієї парадигми програмування повинно витрачатися менше часу на супровід і внесення змін в готовий програмний код, тому роль АОП стає все важливішою.
АОП не є заміною існуючих технологій. Навпаки, також як процедурне програмування використовується в об'єктно-орієнтованому програмуванні (ООП) для реалізації поведінки об'єктів, АОП використовує існуючі підходи для реалізації своїх модулів — аспектів, тобто виконує роль розширення, що дозволяє забезпечити модуляризацию крізної функціональності. Залежно від технології і мови програмування відповідна реалізація АОП володітиме різними можливостями.
3.3.Недоліки аспектного підходу
Зараз аспектно-орієнтований підхід володіє поряд недоліків:
Не повністю пропрацювала методологія АОП-розробки програм. В даний момент закінчений компілятор, що відтестував, є тільки для декількох мов, що обмежує застосування даної технології. З іншого боку, реалізація концепцій АОП тільки на рівні мовних розширень представляється неповною і неефективною. Перспективнішим варто рахувати проникнення самих базових ідей АОП і використання їх на різних рівнях засобів розробки — мов (С++, Pascal), платформ (.NET, Java), і технологій (COM, CORBA і т.д.), по аналогії з вже традиційним використанням ООП.
Недостатньо якісна реалізація розширень мов. В даний час існуючі реалізації АОП-розширень для різних мов і платформ розрізняються по своїх можливостях, але можна виділити загальні риси: кожна реалізація АОП повинна надати механізм опису логіки крізної функціональності і механізм опису крапок програми, в яких дана логіка застосовуватиметься. Проте кожна реалізація по-своєму визначає види крапок скріплення, в яких можна застосувати аспект, а також вирішує питання їх опису, що утрудняє розуміння і використання загальних принципів АОП.
Недостатньо пропрацював механізм прив'язки аспектів до компонентів. У поширених в даний час АОП-реалізаціях точки скріплення описуються в термінах програмних конструкцій — класів, методів, полів класу. При цьому виходить тісний зв'язок між аспектом і компонентом, до якого він застосовується. Логіка прив'язки аспекту до даної точки коду виражена неявно і цілком визначається програмною конструкцією, в термінах якої побудований опис. Тісний зв'язок між аспектом і компонентом робить аспект залежним від компоненту і при цьому порушується одна з основних ідей АОП — незалежність компонентів від вживаних до нього аспектів.
Не повністю досліджені випадки, коли аспекти зручно і доцільно було б застосувати. Цю проблему частково вирішує дана стаття.
3.4.ASPECTJ як одна з реалізацій АОП
АОП можна підтримувати в рамках вже існуючих мов. Так, зокрема, дослідницький центр Xerox PARC розробив систему ASPECTJ, підтримуючу АОП в рамках мови Java. Цей пакет вбудовується в такі системи розробки, як Eclipse, Sun ONE Studio, Forte 4J і Borland JBuilder. У даній роботі ASPECTJ був вибраний через те, що дана реалізація АОП володіє найбільш широкими можливостями.
ASPECTJ — це просте і практичне розширення мови Java, яке додає до Java можливості АОП, що надаються. Пакет ASPECTJ складається з компілятора (ajc), відладчика (ajdb), і генератора документації (ajdoc). Оскільки ASPECTJ є розширенням Java, то будь-яка програма, написана на Java, буде правильною з погляду семантики ASPECTJ. Компілятор ASPECTJ видає байт-код сумісний з віртуальною машиною Java. Оскільки як базова мова для ASPECTJ була вибрана мова Java, то він успадкував від Java всі переваги і спроектований таким чином, що буде легко зрозумілий розробникам Java. Додані розширення стосуються в основному способів завдання правил інтеграції аспектів і java-об'єктів. Дані правила виражаються в ключових поняттях ASPECTJ:
JoinPoint — строго певна точка виконання програми, що асоціюється з контекстом виконання (виклик методу, конструктора, доступ до поля класу, обробник виключення, і т.д.)
Pointcut — набір (зріз) точок JoinPoint що задовольняють заданій умові.
Advice — набір інструкцій мови java, що виконуються до, після або замість кожної з точок виконання (JoinPoint), що входять в заданий зріз (Pointcut)
Aspect — основна одиниця модульної ASPECTJ. У аспектах задаються зрізи точок виконання (Pointcut) і інструкції, які виконуються в точках виконання (Advice)
Introduction — здатність аспекту змінювати структуру Java-класу шляхом додавання нових полів і методів, так і ієрархію класу.
Pointcut і Advice визначають правила інтеграції. Аспект — одиниця, що нагадує клас в ООП, сполучає елементи pointcut і елементи advice разом, і формує модуль на зрізі системи.
Розглянемо приклад, на якому можна зрозуміти, як мова ASPECTJ реалізує принципи АОП. Як приклад візьмемо модель простого графічного редактора. Даний графічний редактор може працювати з двома типами графічних елементів — крапкою і лінією. Діаграма класів графічного редактора представлена на малюнку 8. Класи Point і Line реалізують інтерфейс FigureElement метод переміщення фігури, що містить. Операціями, що впливають на оновлення екрану, є операції переміщення фігур. Піс...