Ответ 1
Почему "против" ? Это не "против" . Вы можете использовать Aspect Ориентированное программирование в сочетании с функциональным программированием, но также в сочетании с объектно-ориентированным. Это не "против" , это "Аспектно-ориентированное программирование с объектно-ориентированным программированием".
Для меня AOP - это своего рода "мета-программирование". Все, что делает АОП, также может быть сделано без него, просто добавив больше кода. AOP просто сохраняет ваш код.
В Википедии есть один из лучших примеров для этого метапрограммирования. Предположим, у вас есть графический класс со многими методами "set...()". После каждого метода набора данные графики изменялись, поэтому графика менялась, и, следовательно, графика должна обновляться на экране. Предположим, что нужно перекрасить графику, которую вы должны назвать "Display.update()". Классический подход состоит в том, чтобы решить это, добавив больше кода. В конце каждого метода набора вы пишете
void set...(...) {
:
:
Display.update();
}
Если у вас есть 3 метода set, это не проблема. Если у вас 200 (гипотетический), становится очень больно добавлять это повсюду. Также, когда вы добавляете новый метод set, вы должны быть уверены, что не забудьте добавить это до конца, иначе вы просто создали ошибку.
AOP разрешает это без добавления большого количества кода, вместо этого вы добавляете аспект:
after() : set() {
Display.update();
}
И это! Вместо того, чтобы самостоятельно писать код обновления, просто сообщите системе, что после достижения pointcut() pointcut он должен запустить этот код, и он запустит этот код. Не нужно обновлять 200 методов, не нужно, чтобы вы не забыли добавить этот код в новый метод set. Кроме того, вам просто нужен pointcut:
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
Что это значит? Это означает, что если метод называется "set *" (* означает, что любое имя может следовать после набора), независимо от того, что возвращает метод (первая звездочка) или какие параметры он принимает (третья звездочка), и это метод MyGraphicsClass, и это class является частью пакета "com.company. *", то это pointcut point(). И наш первый код говорит "после запуска любого метода, который является набором pointcut, запустите следующий код".
Посмотрите, как AOP элегантно решает проблему здесь? Фактически все, описанное здесь, может быть сделано во время компиляции. Препроцессор AOP может просто изменить ваш источник (например, добавить Display.update() в конец каждого метода set-pointcut), прежде чем компилировать сам класс.
Однако этот пример также показывает один из больших недостатков АОП. AOP фактически делает то, что многие программисты считают " Anti-Pattern". Точный шаблон называется " Действие на расстоянии".
Действие на расстоянии - это анти-шаблон (признанный общий ошибка), в котором поведение в одной части программы сильно зависит от трудно или невозможно идентифицировать операций в другой части Программа.
Как новичок в проекте, я могу просто прочитать код любого метода set и считать его сломанным, поскольку он, кажется, не обновляет отображение. Я не смотрю, просто просматривая код set-метода, который после его выполнения для обновления дисплея будет выполнен "волшебный" код. Я считаю это серьезным недостатком! Внося изменения в метод, могут возникнуть странные ошибки. Дальнейшее понимание кода кода кода, в котором некоторые вещи работают корректно, но не очевидны (как я уже сказал, они просто магически работают... как-то), действительно сложно.
Update
Просто чтобы уточнить, что: у некоторых людей может сложиться впечатление, что я говорю, что АОП - это что-то плохое и его не следует использовать. Это не то, что я говорю! AOP - отличная функция. Я просто говорю: "Используйте его осторожно". AOP вызовет проблемы, если вы перепутаете обычный код и AOP для того же Aspect. В приведенном выше примере у нас есть Аспект обновления значений графического объекта и рисования обновленного объекта. Это на самом деле один аспект. Кодирование половины его как обычного кода, а другая половина его в качестве аспекта - вот что добавляет проблему.
Если вы используете AOP для совершенно другого аспекта, например. для ведения журнала вы не столкнетесь с проблемой анти-шаблона. В этом случае новичок в проекте может задаться вопросом: "Откуда берутся все эти сообщения журнала? Я не вижу никаких выходных данных журнала в коде", но это не является большой проблемой. Изменения, внесенные им в программную логику, вряд ли нарушают работу журнала, и изменения, внесенные в лог файл, вряд ли нарушат его программную логику - эти аспекты полностью разделены. Использование AOP для ведения журналов имеет то преимущество, что ваш программный код может полностью сконцентрироваться на том, что он должен делать, и вы все еще можете иметь сложный журнал, без того, чтобы ваш код загромождал сотни сообщений журнала повсюду. Также, когда вводится новый код, волшебные лог-сообщения будут отображаться в нужное время с нужным контентом. Программист-новичок может не понимать, почему они там или откуда они пришли, но поскольку они будут записывать "правильную вещь" в "правильное время", он может просто с радостью принять тот факт, что они есть, и перейти к чему-то еще.
Поэтому хорошим использованием AOP в моем примере было бы всегда регистрировать, если какое-либо значение было обновлено с помощью установленного метода. Это не создаст анти-шаблон и вряд ли станет причиной каких-либо проблем.
Можно сказать, что если вы можете легко злоупотреблять АОП, чтобы создать так много проблем, это плохая идея использовать все это. Однако какую технологию нельзя злоупотреблять? Вы можете злоупотреблять инкапсуляцией данных, вы можете злоупотреблять наследованием. Практически всякая полезная технология программирования может быть нарушена. Считайте язык программирования настолько ограниченным, что он содержит только функции, которые нельзя злоупотреблять; язык, на котором функции могут использоваться только по мере того, как они изначально предназначались для использования. Такой язык был бы настолько ограничен, что он может быть использован даже для программирования в реальном мире.