Аспектно-орієнтоване програмування

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Аспектно-орієнтоване програмування, АОП (англ. aspect-oriented programming, AOP)  — парадигма програмування, яка дозволяє виокремити перехресну (наскрізну) функціональність.

Мета створення[ред.ред. код]

Сучасні програмні системи часто вирішують величезну кількість надскладних завдань, що потребують хороших інженерних навичок від їх розробників та надійності інструментальних засобів розробки. При зростанні складності таких систем зростає і програмний код, розробнику стає все важче охопити всі деталі реалізації системи. При підтримці великих програмних засобів зростає час знаходження та виправлення помилки, ускладнюється додавання нових характеристик, оскільки стає все важче визначити наскільки зміни вплинуть на систему, чи не внесуть додаткових помилок та дефектів. Для вирішення таких завдань застосовують різноманітні інженерні засоби, як от багатофункціональні середовища розробки, шаблони проектування, готові програмні каркаси тощо.
Часто згадуваним недоліком об’єктно-орієнтованого підходу є неможливість локалізації наскрізної функціональності в одному класі[1]. Як приклад такої функціональності часто називають необхідність ведення журналів подій, керування винятковими ситуаціями, перевірку прав доступу. Код, що відповідає за дану функціональність, часто розкиданий по різних класах. Це, з одного боку, не дозволяє сконцентрувати увагу на основній бізнес-логіці класу і ускладнює читання коду. З іншого боку, ускладнюється внесення змін у методи роботи наскрізної функціональності, що не завжди можна виправити правильним використанням інтерфейсів чи шаблонів проектування. Наразі аспектно-орієнтований підхід часто використовують для реалізації вищенаведених прикладів, проте, як зауважують деякі автори[2], на цьому сфера застосування аспектно-орієнтованого підходу не обмежуються, оскільки він може бути використаний для проектування будь-яких систем, що містять наскрізну функціональність.
В результаті наявності зайвої перехресної функціональності розроблюваний модуль містить заплутаний код, що задовольняє різні програмні вимоги. Негативні властивості такого коду[3]:

  • Розкиданий код. Оскільки наскрізна функціональність зачіпає багато модулів системи, то й виклики цієї функціональності будуть розкидані по всій системі. Наприклад, якщо програма містить засоби моніторингу продуктивності роботи з базою даних, то й виклики цієї функціональності будуть розміщені всюди, де потрібно працювати з базою даних. Наявність розкиданого коду має негативний вплив на проектування та реалізацію системи;
  • Важкість відслідковування призначення модуля, оскільки він містить одночасно функціональність для задоволення різних вимог;
  • Складність або неможливість повторного використання модуля у програмах з іншою наскрізною функціональністю;
  • Велика ймовірність помилок. Наявність коду для реалізації функціональності різного роду в одному модулі може призвести до того, що жодне із завдань не отримає достатньої уваги розробника;
  • Важкість супроводу. Якщо з'являється необхідність у зміні наскрізною функціональності, така зміна зачіпає багато модулів системи, що в кінцевому рахунку може призвести до проблем сумісності.

Для вирішення завдання локалізації наскрізної функціональності була розроблена методологія аспектно-орієнтованого програмування (АОП). Основні ідеї АОП були сформульовані ідеологом методології Г. Кінжалесом[4]. Він також розробив найпопулярнішу надбудову мови програмування Java для роботи з аспектами – AspectJ.

Основні поняття[ред.ред. код]

До основних понять аспектно-орієнованого програмування належать[5]:

  • Аспект (англ. aspect) — модуль або клас, який реалізує наскрізну функціональність. Аспект змінює поведінку іншого коду, застосовуючи поради в точках з'єднання, визначених деяким зрізом;
  • Порада (англ. advice) — додаткова логіка, код, який повинен бути викликаний з точки з'єднання. Порада може бути виконана до, після або замість точки з'єднання;
  • Мета (англ. target) — об'єкт, до якого будуть застосовуватися поради;
  • Точка з'єднання (англ. join point) — точка в виконуваній програмі (виклик методу, створення об'єкта, звернення до змінної), де слід застосувати пораду;
  • Зріз (англ. pointcut) — набір точок з'єднання. Зріз визначає, чи підходить дана точка з'єднання до заданої поради;
  • Впровадження (англ. introduction) — зміна структури класу та/або зміна ієрархії успадкування для додавання функціональності аспекту в чужорідний код;
  • Переплетення (англ. weaving) — зв'язування об'єктів з відповідними аспектами (можливе на етапі компіляції, завантаження або виконання програми).

Переваги використання[ред.ред. код]

Аспектно-орієнтований підхід розглядає програмну систему як набір модулів, кожен з яких виражає особливість функціонування системи. При проектуванні системи розробник вибирає модулі так, щоб кожен із них реалізовував певну функціональну вимогу. Натомість в рамках об'єктно-орієнтованого підходу реалізація деяких вимог до програми часто не може бути локалізована в окремому модулі, в результаті чого код, що відображає такі функціональні завдання, буде знаходитись у різних модулях (наприклад, код ведення журналу подій).
Як підтверджують дослідження, аспектно-орієнтований підхід зменшує складність розроблюваного коду[6]. Традиційною характеристикою розміру програм є кількість рядків вихідного коду. Наприклад, однією з таких метрик є оцінки Холстеда. Основу цієї метрики складають чотири вимірювані характеристики програми:

  • Число унікальних операторів програми;
  • Число унікальних операндів програми;
  • Загальне число операторів в програмі;
  • Загальне число операндів в програмі.

Друга найінформативніша група оцінок складності програм — метрики складності потоку управління програм. Як правило, за допомогою цих оцінок оперують або щільністю керівних переходів усередині програм, або взаємозв'язками цих переходів.
В результаті проведених досліджень на основі розробки системи авторизації з використанням аспектно-орієнтованого підходу встановлено, що метрики коду в цілому на 10–40% нижче ніж в ООП реалізації, що позитивним чином впливає на систему, оскільки на кожну метрику (ресурс) буде витрачено менше часу.

Способи застосування[ред.ред. код]

Використання аспектно-орієнтованого підходу не вимагає повністю відмовитись від об’єктно-орієнтованої реалізації, оскільки його можна впроваджувати лише частково. Більше того, такий підхід ефективно доповнює об'єктно-орієнтований код. Як показують дослідження аспектно-орієнтованих програм[7], близько 2% їх коду пов'язана з специфічними механізмами мови аспектно-орієнтованого програмування (наприклад, AspectJ); 12% - з базовими механізмами; 86% є об'єктно-орієнтованим.
Саме тому існують роботи по вдосконаленню програмних каркасів (англ. frameworks) за допомогою технології аспектів[8]. Об'єктно-орієнтований програмний каркас містить компоненти, що становлять ядро функціонування та компоненти, що містять додаткову функціональність. При використанні фреймворку стандартна функціональність розширюється за допомогою наслідування. Застосування аспектно-орієнтованого підходу дозволяє, з одного боку, розділити на окремі модулі наскрізну функціональність ядра, з іншого боку — легко додавати функціональність використовуючи аспекти ядра.
Ефективно можна застосовувати аспектно-орієнтоване програмування для оптимізації шаблонів проектування[9]. Першою значною перевагою є здатність локалізувати код шаблону проектування в одному аспекті або парі тісно пов'язаних аспектів (на відміну від мови Java, де код шаблону може бути розкиданим по багатьом класам). Можливість бачити весь код в одному місці має ряд суттєвих переваг:

  • Читачі коду можуть легше зрозуміти шаблон, якщо він весь знаходиться в одному місці;
  • Розробники можуть використати зрозумілі назви для опису аспекту, що дозволить іншим розробникам легше зрозуміти шаблон;
  • Якщо виникла необхідність змінити реалізацію шаблону, це можна зробити в одному місці, замість того, щоб шукати реалізацію по всій системі.

Дослідження використання аспектно-орієнтованого підходу проводилися в різних галузях. Наприклад, при розробці мобільних Java-ігор можна оптимізувати керування ігровим екраном, створення ігрових персонажів, завантаження і відображення малюнків тощо[10]. Крім того, за допомогою точок з'єднання можна впроваджувати необов'язкову функціональність, наприклад відображення фонових зображень лише на пристроях певного типу.
Запропоновані методи застосування аспектно-орієнтованого підходу для розробки багатоагентних систем[11], де агент – автономна програмна одиниця, що при виконанні завдання реагує на навколишнє середовище та спілкується з іншими програмами-агентами (наприклад, програми купівля товарів в Інтернеті). В даному випадку аспекти можна застосувати для проектування кількох платформ комунікації агентів, додаткових можливостей навчання, різних ролей та протоколів взаємодії.

Недоліки[ред.ред. код]

Є кілька причин, що стримують розробників від активного застосування технології аспектно-орієнтованого програмування (хоча ці недоліки спростовуються в деяких роботах[12]):

  • Недостатня розвиненість мовних засобів та конструкцій, що дозволяють запрограмувати аспекти;
  • Необхідність розробки найкращих компіляторів для оптимізації аспектного коду;
  • Відсутність достатньо розвинутих засобів підтвердження ефективності використання даного підходу в кожному конкретному випадку;
  • Певні складнощі відлагодження та тестування розроблених програм.

Проте найважливішим стримуючим фактором є необхідність формування своєрідного мислення для проектування систем в термінах наскрізної функціональності. Тому аспектно-орієнтований підхід не здобув значного поширення, проте є перспективної технологією для вивчення[13].

Засоби розробки[ред.ред. код]

Для практичного впровадження аспектно-орієнтованого підходу використовуються різні інструментальні засоби, одним з яких є розширення мови Java під назвою AspectJ, що дозволяє впровадити аспектну функціональність в розроблювані Java-проекти за допомогою розширення синтаксису або анотацій. При створенні AspectJ перед її властивостями ставилися наступні вимоги[14]:

  • Зворотна сумісність — всі Java-програми повинні успішно виконуватися на AspectJ;
  • Сумісність платформи – всі AspectJ-програми повинні запускатися на стандартній віртуальній машині;
  • Сумісність засобів розробки — включає середовище розробки, засоби документування і проектування;
  • Сумісність програмування — програмування на AspectJ повинне справляти враження розширення мови Java.

Крім цього, існують й інші Java-фреймворки для роботи з аспектами, порівняльна характеристика яких наводиться у таблиці[15]:

Feature/issue AspectJ AspectWerkz JBoss AOP Spring dynaaop
Weaving time Compile/load-time Compile/load-time Compile/load/run Runtime Runtime
Transparency Transparent Transparent Choice Factory Factory
Per-instance aspects No No Yes Yes Yes
Constructor, field, throw, and cflow interception All All Some Some None
Annotations No Yes Yes Yes No
Standalone Yes Yes Yes No Yes
AOP Alliance No No No Yes Yes
Affiliation IBM BEA JBoss Spring ?

Виноски[ред.ред. код]