Чи певні проблеми вирішуються більш елегантно з AOP?


19

Я зіткнувся з ідеєю програмування, орієнтованого на аспекти, і в мене є певні проблеми.

Основна ідея, здається, полягає в тому, що ми хочемо взяти наскрізні проблеми, які недостатньо модулюються, використовуючи об'єкт, і модулювати їх. Це все дуже добре і добре.

Але реалізація AOP виглядає як модифікація коду поза модулем. Так, наприклад, може бути записаний аспект, який змінює те, що відбувається, коли певний об'єкт передається як параметр у функції. Це, здається, суперечить ідеї модулів. Я не повинен мати змогу змінювати поведінку модуля поза цим модулем, інакше вся точка модулів перевернута. Але аспекти, здається, роблять саме це!

В основному, аспекти, схоже, є формою виправлення коду. Це може бути корисно для деяких швидких злому; але, як загальний принцип, можливо, це не те, що ви хочете робити. Асистемно-орієнтоване програмування, як мені здається, сприймає погану практику і переходить до загального принципу проектування.

Чи хороша практика АОП? Чи певні проблеми програмування вирішуються більш елегантно за допомогою AOP?


ах, знаменитий патч мавп!
Muad'Dib

1
Я відредагував питання, щоб поліпшити його тон, і проголосував за його повторне відкриття.
Роберт Харві

Тут питання також було задано в іншій формі: programmers.stackexchange.com/questions/19344/…
Пітер Бауфтон

Відповіді:


19

Програмування, орієнтоване на аспекти, дозволяє робити певні типи програмування, які важко обійтися без зайвого розсіювання коду по всій програмі чи бібліотеці, що не пов’язане з основними функціями вашого програмного забезпечення (тобто наскрізні проблеми). Приклади включають:

  1. Ведення журналу та моніторинг
  2. Аналіз продуктивності
  3. Налагодження та відстеження
  4. Скасувати функціональність
  5. Перевірка входів та виходів
  6. Перетворює поведінку існуючих об'єктів
  7. Об'єктні фільтри
  8. Впровадження безпеки
  9. Управління транзакціями

Обмежуючи такі наскрізні проблеми в одній частині програми, а потім посилаючись на ці особливості в коді за допомогою атрибутів, перехоплення виклику методу або динамічних проксі, ви дозволяєте інкапсуляцію наскрізної поведінки; це має всі переваги (тобто єдину точку модифікації), інкапсуляція забезпечить деінде у вашій програмі.

Ключовим моментом тут є те, що AOP інкапсулює поведінку, яка є 1) загальною для всієї програми та 2) периферійною основними функціональними можливостями програми.


7

Пізно в грі, але я надаю це для пізніших розробників, які можуть натрапити на це питання.

Я б настійно радив проти AOP, якщо ваша програма залежить від її роботи. Аспекти працюють так:

  • Поради (додаткова поведінка) застосовуються до
  • Точки приєднання (місця, де може бути доданий додатковий код, такий спосіб починається чи закінчується, або коли спрацьовує певна подія)
  • ... де точка (шаблон, який визначає, чи відповідає збіг заданої точки з'єднання)

Для кожного, хто довгий час займався комп’ютером, факт, що використовуються візерунки, може стати уважним уважною увагою. Отож ось приклад точки, яка відповідає будь-якому методу, названому setнезалежно від аргументів:

call(* set(..))

Отож, це досить глибока точкова точка, і повинно бути зрозуміло, що рекомендується обережно поводитися з цим (не каламбур), оскільки ви застосовуєте поради щодо багатьох речей.

Або чортів, давайте застосовувати поради до всього , незалежно від імені чи підпису!

execution(* *(..))

Отже, очевидно, що ми повинні бути обережними, оскільки тут багато сил, але це не аргумент проти аспектів - це аргумент для обережності, оскільки тут багато потужності, а відповідність шаблонів може легко зійти з ладу (просто натисніть на вашу улюблену пошукову систему для aop клопи і веселитися).

Ось ось, що виглядає як відносно безпечний пункт:

pointcut setter(): target(Point) &&
                   ( call(void setX(int)) ||
                     call(void setY(int)) );

Це прямо дає поради, якщо знайдені методи, названі setXабо setYна Pointоб’єкті. Методи можуть отримувати лише ints, і вони повинні бути void. Виглядає досить безпечно, правда? Ну, це безпечно, якщо ці методи існують, і ви застосували правильну пораду. Якщо ні, то занадто погано; це мовчки не вдається.

Для прикладу, друг намагався налагодити додаток Java, де кожен раз у чудовий час він повертав би невірні дані. Це було нечастою невдачею і, схоже, не було пов'язане з якоюсь конкретною подією чи даними зокрема. Це була помилка з різьбленням, те, що загалом важко перевірити або виявити. Як виявляється, вони використовували аспекти, щоб заблокувати методи та зробити їх "безпечними для потоків", але програміст перейменував метод, і точкова точка не змогла відповідати йому, тим самим спричинивши мовчазну поломку програми.

Таким чином, я кажу людям, що якщо вони повинні використовувати AOP, вони розглядають такі аспекти, як винятки: у добре розробленій системі, і якщо нічого не піде не так, їх можна буде видалити, а програмне забезпечення все ще працює належним чином. Однак якщо функціональність програми залежить від AOP, ви вводите в свою програму неміцність, що не є обґрунтованою.

Таким чином, ведення журналів, налагодження та відстеження - це чудові приклади поведінки, ідеальної для аспектів, але безпеки? Ні. Безпека нитки? Ні.

Щоб отримати надійну альтернативу AOP, ознайомтеся з ознаками . Замість того, щоб бути прив'язаними до мови, вони інтегруються в неї безпосередньо, не потребують IDE, що «знає ознаки» (хоча це може допомогти) і мають збої в процесі компіляції, якщо необхідних методів немає. Риси виконують набагато чіткішу роботу з вирішення проблем, оскільки проблема була краще визначена з самого початку. Я їх широко використовую, і вони фантастичні.


Замість того, щоб стверджувати, що AOP не слід використовувати для основної функціональності, може бути більш доречним сказати, що точкові вирізи, які покладаються на назви методів, є поганою ідеєю. Я, мабуть, стверджую, що блокування та синхронізація також не є гарними випадками використання для AOP.
Код Блінг

2

Одна з ситуацій, в якій AOP може бути єдиним гідним, а також практичним рішенням, коли у вас немає доступу до вихідного коду . Щоб скористатися устареним старим прикладом наскрізного концерну «Вирубка лісу»:

Скажімо, ви хочете записати потік керування у сторонній бібліотеці, яку ви споживаєте. У вас є власний код, повністю забезпечений операторами журналу. Однак для цієї бібліотеки у вас немає джерела, що унеможливлює додавання заяв реєстрації. Так як ви робите мають байткод, АОП дозволяє інструменту , що третя сторона бібліотеки в будь-якому випадку.

І якщо ви все-таки створюєте аспект журналу, ви можете також розглянути можливість впровадження протоколу за допомогою AOP і через власний код.


Ведення журналів - це "цікаві" речі. Як ви можете робити інші речі, крім "введення з цими параметрами" та "виходу" з протоколу AOP?

@Thorbjorn: Реєстрація / налагодження / відстеження - лише одна з багатьох областей функціонування, з якими може допомогти AOP. Я використав це як приклад, щоб проілюструвати свою думку. Я намагаюся зробити те, що AOP надає вам більше контролю над стороннім байт-кодом.
Джозеф Таненбаум

звичайно, але мені дуже хотілося знати, чи журнал AOP може зробити більше, ніж просто вхід-вихід?

Це залежить від інструменту AOP, який ви використовуєте, але, безумовно, є обмеження в тому, що ви можете зробити. Вийти за межі журналу входу-виходу може бути неможливо.
Джозеф Таненбаум
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.