Аспектно-ориентированное программирование против объектно-ориентированного программирования - PullRequest
182 голосов
/ 24 октября 2008

Как и большинство разработчиков здесь и во всем мире, я разрабатывал программные системы с использованием методов объектно-ориентированного программирования (ООП) в течение многих лет. Поэтому, когда я читаю, что аспектно-ориентированное программирование (AOP) решает многие проблемы, которые традиционные ООП не решают полностью или напрямую, я замираю и думаю, реально ли это?

Я прочитал много информации, пытаясь изучить ключи этой парадигмы АОП, и я нахожусь в одном месте, поэтому я хотел лучше понять ее преимущества в разработке реальных приложений.

У кого-нибудь есть ответ?

Ответы [ 6 ]

298 голосов
/ 24 октября 2008

Почему "против"? Это не "против". Вы можете использовать Аспектно-ориентированное программирование в сочетании с функциональным программированием, а также в сочетании с Объектно-ориентированным. Это не «против», это «Аспектно-ориентированное программирование с Объектно-ориентированным программированием».

Для меня АОП - это своего рода «метапрограммирование». Все, что делает AOP, также может быть сделано без добавления кода. АОП просто спасает вас от написания этого кода.

В Википедии есть один из лучших примеров этого метапрограммирования. Предположим, у вас есть графический класс с множеством методов set ... (). После каждого метода установки данные графики менялись, поэтому графика изменялась, и, следовательно, графика должна обновляться на экране. Предположим, что для перерисовки графики вы должны вызвать «Display.update ()». Классический подход состоит в том, чтобы решить эту проблему, добавив больше кода . В конце каждого метода набора вы пишете

void set...(...) {
    :
    :
    Display.update();
}

Если у вас есть 3 set-метода, это не проблема. Если у вас есть 200 (гипотетически), становится очень больно добавлять это везде. Кроме того, всякий раз, когда вы добавляете новый метод set, вы должны обязательно не забыть добавить его в конец, иначе вы только что создали ошибку.

AOP решает эту проблему без добавления тонны кода, вместо этого вы добавляете аспект:

after() : set() {
   Display.update();
}

И это все! Вместо того, чтобы писать код обновления самостоятельно, вы просто сообщаете системе, что после достижения точки set (), она должна запустить этот код и запустить этот код. Не нужно обновлять 200 методов, не нужно обязательно добавлять этот код в новый метод set. Кроме того, вам просто нужен pointcut:

pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);

Что это значит? Это означает, что если метод называется «set *» (* означает, что после set может следовать любое имя), независимо от того, что метод возвращает (первая звездочка) или какие параметры он принимает (третья звездочка) метод MyGraphicsClass и , этот класс является частью пакета "com.company. *", тогда это pointcut set (). И наш первый код говорит: « после того, как запустит любой метод, который является заданным значением, запустите следующий код».

Посмотрите, как AOP элегантно решает проблему здесь? На самом деле все описанное здесь может быть сделано во время компиляции. Препроцессор AOP может просто изменить ваш источник (например, добавив Display.update () в конец каждого метода set-pointcut), прежде чем даже скомпилировать сам класс.

Однако в этом примере также показан один из больших недостатков АОП. На самом деле AOP делает то, что многие программисты считают « Anti-Pattern ». Точная схема называется « Действие на расстоянии ».

Действие на расстоянии анти-шаблон (признанный общий ошибка) в котором поведение в одной части программы сильно варьируется в зависимости от трудно или невозможно идентифицировать операции в другой части программа.

Будучи новичком в проекте, я мог бы просто прочитать код любого метода set и считать его неработающим, так как кажется, что он не обновляет отображение. Я не вижу , просто глядя на код метода set, что после его выполнения какой-то другой код будет "магическим образом" выполняться для обновления отображения. Я считаю это серьезным недостатком! Внося изменения в метод, могут появиться странные ошибки. Дальнейшее понимание потока кода, в котором некоторые вещи работают правильно, но не очевидно (как я уже сказал, они просто волшебным образом работают ... как-то), действительно сложно.

Обновление

Просто чтобы уточнить: у некоторых людей может сложиться впечатление, что я говорю, что АОП - это что-то плохое и не должно использоваться. Это не то, что я говорю! АОП на самом деле отличная особенность. Я просто говорю «Используйте это осторожно». AOP вызовет проблемы, только если вы смешаете обычный код и AOP для одного и того же Aspect . В приведенном выше примере у нас есть аспект обновления значений графического объекта и рисования обновленного объекта. Это на самом деле один аспект. Кодирование половины этого как нормального кода, а другая половина как аспекта - вот что добавляет проблему.

Если вы используете АОП для совершенно другого аспекта, например, для регистрации вы не столкнетесь с проблемой анти-паттернов. В этом случае новичок в проекте может спросить: «Откуда берутся все эти сообщения журнала? Я не вижу никакого вывода журнала в коде», но это не большая проблема. Изменения, которые он вносит в программную логику, вряд ли сломают средство ведения журнала, а изменения, внесенные в средство ведения журнала, вряд ли сломают его логику программы - эти аспекты полностью разделены. Преимущество использования AOP для ведения журнала состоит в том, что программный код может полностью сконцентрироваться на выполнении того, что он должен делать, и вы все равно можете вести сложное ведение журнала, при этом ваш код не будет загроможден сотнями сообщений журнала везде. Кроме того, когда вводится новый код, сообщения с магическим журналом будут появляться в нужное время с правильным содержанием. Программист-новичок может не понимать, почему они там или откуда они пришли, но, поскольку они будут записывать «правильные вещи» в «нужное время», он может просто с радостью принять тот факт, что они есть, и перейти к чему-то другому. .

Таким образом, хорошее использование AOP в моем примере будет всегда регистрировать, если какое-либо значение было обновлено с помощью метода set. Это не создаст анти-паттерн и вряд ли когда-либо станет причиной каких-либо проблем.

Можно сказать, что если вы легко злоупотребляете AOP для создания такого количества проблем, плохая идея использовать все это. Однако какими технологиями нельзя злоупотреблять? Вы можете злоупотреблять инкапсуляцией данных, вы можете злоупотреблять наследованием. Практически все полезные технологии программирования могут быть использованы неправильно. Рассмотрим язык программирования настолько ограниченный, что он содержит только те функции, которыми нельзя злоупотреблять; язык, в котором функции могут использоваться только так, как они изначально были предназначены для использования. Такой язык будет настолько ограничен, что спорно, если он может быть даже использовать для реального мира программирования.

27 голосов
/ 24 октября 2008

аспектно-ориентированное программирование обеспечивает хороший способ реализации сквозных задач, таких как регистрация, безопасность. Эти сквозные концепции представляют собой кусочки логики, которые должны применяться во многих местах, но на самом деле не имеют ничего общего с бизнес-логикой.

Вы не должны рассматривать АОП как замену ООП, а скорее как хорошее дополнение, которое делает ваш код более чистым, слабосвязанным и ориентированным на бизнес-логику. Таким образом, применяя АОП, вы получите 2 основных преимущества:

  1. Логика для каждой задачи теперь в одном месте, а не разбросана по всей базе кода.

  2. классы более чистые, так как они содержат код только для своей основной задачи (или основной функциональности), а вторичные проблемы были перенесены в аспекты.

27 голосов
/ 24 октября 2008

ООП и АОП не являются взаимоисключающими. АОП может быть хорошим дополнением к ООП. AOP особенно удобен для добавления стандартного кода, такого как ведение журнала, отслеживание производительности и т. Д., К методам без засорения кода метода этим стандартным кодом.

10 голосов
/ 24 октября 2008

Я думаю, что нет общего ответа на этот вопрос, но следует отметить, что АОП не заменяет ООП, но добавляет некоторые функции разложения, которые обращаются к так называемой тирании доминирующий состав ( 1 ) (или сквозные проблемы).

Это, безусловно, помогает в определенных случаях, пока вы контролируете инструменты и языки, используемые для конкретного проекта, но также добавляет новый уровень сложности в отношении взаимодействия аспектов и необходимости в дополнительных инструментах, таких как AJDT чтобы понять вашу программу.

Грегор Кичалес однажды выступил с интересной вступительной речью по AOP на Google Tech Talks, которую я рекомендую посмотреть: Аспектно-ориентированное программирование: радикальное исследование модульности .

8 голосов
/ 24 октября 2008

Прежде всего АОП не заменит ООП. АОП расширяет ООП. Идеи и практики ООП остаются актуальными. Хороший дизайн объекта, вероятно, облегчит его расширение аспектами.

Я думаю, что идеи, которые приносит АОП, важны. Нам нужно разработать способы реализации сквозных задач для разных классов в вашей программе без необходимости изменения самих классов. Но я думаю, что в конечном итоге АОП просто станет частью других инструментов, которые мы используем, а не отдельным инструментом или техникой. Мы уже видим, как это происходит.

Пара динамических языков, таких как Ruby и Python, имеют языковые конструкции, такие как миксины, которые решают те же проблемы. Это очень похоже на АОП, но лучше интегрировано в язык.

Spring и Castle и пара других структур внедрения зависимостей имеют опции для добавления поведения к классам, которые они вводят. Это способ выполнения ткачества во время выполнения, и я думаю, что у этого есть большой потенциал.

Я не думаю, что вам придется изучать совершенно новую парадигму, чтобы использовать АОП. Идеи интересны, но постепенно усваиваются существующими инструментами и языками. Просто будьте в курсе и опробуйте эти инструменты.

1 голос
/ 13 октября 2010

AOP - это новая парадигма программирования, связанная с этой концепцией. Аспектом является программный объект, реализующий конкретную нефункциональную часть приложения.

Я думаю, что эта статья - хорошее место, чтобы начать с Аспектно-ориентированного программирования: http://www.jaftalks.com/wp/index.php/introduction-to-aspect-oriented-programming/

...