Аспектно-ориентированное программирование против объектно-ориентированного программирования
Как и большинство разработчиков здесь и во всем мире, я разрабатывал программные системы с использованием методов объектно-ориентированного программирования (ООП) в течение многих лет. Поэтому, когда я читаю, что аспектно-ориентированное программирование (AOP) решает многие проблемы, которые традиционные ООП не решают полностью или напрямую, я замираю и думаю, реально ли это?
Я прочитал много информации, пытаясь изучить ключи этой парадигмы АОП, и я нахожусь в одном месте, поэтому я хотел лучше понять ее преимущества в разработке реальных приложений.
У кого-нибудь есть ответ?
6 ответов
Почему "против"? Это не "против". Вы можете использовать Аспектно-ориентированное программирование в сочетании с функциональным программированием, а также в сочетании с Объектно-ориентированным. Это не "против", это "Аспектно-ориентированное программирование с объектно-ориентированным программированием".
Для меня АОП - это своего рода "метапрограммирование". Все, что делает AOP, также может быть сделано без добавления кода. АОП просто спасает вас писать этот код.
В Википедии есть один из лучших примеров этого метапрограммирования. Предположим, у вас есть графический класс с множеством методов set... (). После каждого установленного метода данные графики менялись, поэтому графика изменялась, и, следовательно, графика должна обновляться на экране. Предположим, что для перерисовки графики вы должны вызвать "Display.update ()". Классический подход состоит в том, чтобы решить эту проблему, добавив больше кода. В конце каждого метода набора вы пишете
void set...(...) {
:
:
Display.update();
}
Если у вас есть 3 set-метода, это не проблема. Если у вас есть 200 (гипотетически), становится больно добавлять это везде. Кроме того, всякий раз, когда вы добавляете новый метод set, вы должны быть уверены, что не забыли добавить его в конец, иначе вы просто создали ошибку.
АОП решает это без добавления тонны кода, вместо этого вы добавляете аспект:
after() : set() {
Display.update();
}
И это все! Вместо того, чтобы писать код обновления самостоятельно, вы просто сообщаете системе, что после достижения точки set() она должна запустить этот код и запустить этот код. Не нужно обновлять 200 методов, не нужно обязательно добавлять этот код в новый метод set. Кроме того, вам просто нужен pointcut:
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
Что это значит? Это означает, что если метод называется "set*" (* означает, что после set может следовать любое имя), независимо от того, что метод возвращает (первая звездочка) или какие параметры он принимает (третья звездочка), и это метод MyGraphicsClass, и это class является частью пакета "com.company.*", тогда это точка (set). И наш первый код говорит: "после запуска любого метода, который является заданным pointcut, запустите следующий код".
Посмотрите, как АОП элегантно решает проблему здесь? На самом деле все описанное здесь может быть сделано во время компиляции. Препроцессор AOP может просто изменить ваш исходный код (например, добавив Display.update () в конец каждого метода set-pointcut), прежде чем даже скомпилировать сам класс.
Тем не менее, этот пример также показывает один из больших недостатков АОП. AOP на самом деле делает то, что многие программисты считают " анти-паттерном". Точная схема называется " Действие на расстоянии".
Действие на расстоянии - это антишаблон (общепризнанная распространенная ошибка), при котором поведение в одной части программы сильно меняется в зависимости от того, трудно или невозможно идентифицировать операции в другой части программы.
Как новичок в проекте, я мог бы просто прочитать код любого метода set и считать его неисправным, так как кажется, что он не обновляет отображение. Я не вижу, просто глядя на код метода set, что после его выполнения какой-то другой код будет "магически" выполняться для обновления отображения. Я считаю это серьезным недостатком! Внося изменения в метод, могут появиться странные ошибки. Дальнейшее понимание потока кода, в котором определенные вещи работают правильно, но не очевидно (как я уже сказал, они просто волшебным образом работают... как-то), действительно сложно.
Обновить
Просто чтобы уточнить: у некоторых людей может сложиться впечатление, что я говорю, что АОП - это что-то плохое и не должно использоваться. Это не то, что я говорю! АОП на самом деле отличная особенность. Я просто говорю "Используйте это осторожно". AOP вызовет проблемы, только если вы смешаете обычный код и AOP для одного и того же аспекта. В приведенном выше примере у нас есть аспект обновления значений графического объекта и рисования обновленного объекта. Это на самом деле один аспект. Кодирование половины этого как нормального кода, а другая половина как аспекта - вот что добавляет проблему.
Если вы используете AOP для совершенно другого аспекта, например, для регистрации, вы не столкнетесь с проблемой анти-паттернов. В этом случае новичок в проекте может спросить: "Откуда берутся все эти сообщения журнала? Я не вижу никакого вывода журнала в коде", но это не большая проблема. Изменения, которые он вносит в программную логику, вряд ли сломают средство ведения журнала, а изменения, внесенные в средство ведения журнала, вряд ли сломают его логику программы - эти аспекты полностью разделены. Преимущество использования AOP для ведения журнала состоит в том, что программный код может полностью сконцентрироваться на выполнении того, что он должен делать, и вы все равно можете вести сложную запись в журнал, не перегружая свой код сотнями сообщений журнала повсюду. Кроме того, когда вводится новый код, сообщения с магическим журналом будут появляться в нужное время с нужным содержанием. Программист-новичок может не понимать, почему они там или откуда они пришли, но, поскольку они будут записывать "правильные вещи" в "нужное время", он может просто с радостью принять тот факт, что они там, и перейти к чему-то другому.,
Таким образом, хорошим примером использования АОП в моем примере будет всегда входить в систему, если какое-либо значение было обновлено с помощью метода set. Это не создаст анти-паттерн и вряд ли когда-либо станет причиной каких-либо проблем.
Кто-то может сказать, что если вы можете легко злоупотреблять AOP, создавая так много проблем, плохая идея использовать все это. Однако какими технологиями нельзя злоупотреблять? Вы можете злоупотреблять инкапсуляцией данных, вы можете злоупотреблять наследованием. Практически все полезные технологии программирования могут быть использованы неправильно. Рассмотрим язык программирования настолько ограниченный, что он содержит только те функции, которыми нельзя злоупотреблять; язык, в котором функции могут использоваться только так, как они изначально были предназначены для использования. Такой язык будет настолько ограничен, что спорно, если он может быть даже использовать для реального мира программирования.
Аспектно -ориентированное программирование обеспечивает хороший способ реализации сквозных задач, таких как ведение журнала и безопасность. Эти сквозные концепции представляют собой кусочки логики, которые должны применяться во многих местах, но на самом деле не имеют ничего общего с бизнес-логикой.
Вы не должны рассматривать AOP как замену OOP, а скорее как хорошее дополнение, которое делает ваш код более чистым, слабосвязанным и ориентированным на бизнес-логику. Таким образом, применяя АОП, вы получите 2 основных преимущества:
Логика для каждой проблемы теперь в одном месте, а не разбросана по всей базе кода.
классы более чистые, поскольку они содержат код только для своей основной задачи (или основной функциональности), а второстепенные проблемы перенесены в аспекты.
ООП и АОП не являются взаимоисключающими. АОП может быть хорошим дополнением к ООП. AOP особенно удобен для добавления стандартного кода, такого как ведение журнала, отслеживание производительности и т. Д., В методы без засорения кода метода этим стандартным кодом.
Я думаю, что нет общего ответа на этот вопрос, но следует отметить, что АОП не заменяет ООП, а добавляет некоторые функции декомпозиции, которые обращаются к так называемой тирании доминирующего состава ( 1) (или сквозных проблем).
Это, безусловно, помогает в определенных случаях, пока вы контролируете инструменты и языки, используемые для конкретного проекта, но также добавляет новый уровень сложности в отношении взаимодействия аспектов и необходимости в дополнительных инструментах, таких как AJDT, чтобы все еще понимать ваша программа
Грегор Кичалес однажды выступил с интересной вступительной речью по AOP на Google Tech Talks, которую я рекомендую посмотреть: Аспектно-ориентированное программирование: радикальное исследование модульности.
Я опоздал с этим вопросом, но это одна из моих любимых тем, поэтому позвольте мне поделиться своим мнением.
ООП в основном используется для организации вашей бизнес-логики, в то время как АОП помогает организовать ваши нефункциональные вещи, такие как аудит, ведение журнала, управление транзакциями, безопасность и т. Д.
Таким образом, вы можете отделить бизнес-логику от неигровой логики, что сделает код более чистым.
Преимущество Otter в том, что вы можете применять совет (пример аудита) очень последовательно, без реализации какого-либо интерфейса, который дает большую гибкость для модификации, не затрагивая бизнес-логику.
Прежде всего АОП не заменит ООП. АОП расширяет ООП. Идеи и практики ООП остаются актуальными. Хороший дизайн объекта, вероятно, облегчит его расширение аспектами.
Я думаю, что идеи, которые приносит АОП, важны. Нам нужно разработать способы реализации сквозных задач для разных классов в вашей программе без необходимости изменения самих классов. Но я думаю, что в конечном итоге АОП просто станет частью других инструментов, которые мы используем, а не отдельным инструментом или техникой. Мы уже видим, как это происходит.
Пара динамических языков, таких как Ruby и Python, имеют языковые конструкции, такие как миксины, которые решают те же проблемы. Это очень похоже на АОП, но лучше интегрировано в язык.
Spring и Castle, а также пара других сред внедрения зависимостей имеют опции для добавления поведения в классы, которые они вводят. Это способ выполнения ткачества во время выполнения, и я думаю, что у этого есть большой потенциал.
Я не думаю, что вам придется изучать совершенно новую парадигму, чтобы использовать АОП. Идеи интересны, но постепенно усваиваются существующими инструментами и языками. Просто будьте в курсе и опробуйте эти инструменты.
АОП - это новая парадигма программирования, связанная с этой концепцией. Аспект представляет собой программный объект, реализующий конкретную нефункциональную часть приложения.
Я думаю, что эта статья - хорошее место, чтобы начать с Аспектно-ориентированного программирования: http://www.jaftalks.com/wp/index.php/introduction-to-aspect-oriented-programming/