Кстати, я выступаю на Scala Days 2011 по той же теме .Основная идея такая же, как у Кима и Дина.Тем не менее, когда дело доходит до полного спектра сквозных проблем, сходство и различия становятся более нюансированными.
На одном конце спектра , существуют не совсем сквозные проблемы, такие как кеширование,Когда основной язык не поддерживает функции более высокого порядка (например, Java), реализация проблемы как аспекта становится привлекательной.Например, с AspectJ и подходом аннотации вы можете сказать:
@Cacheable(keyScript="#account.id")
public double getNetWorth(Account account) {
... expensive computation
}
Но с функцией более высокого порядка в Scala вы можете сделать:
def getNetWorth(account: Account) : Double = {
cacheable(keyScript=account.id) {
... expensive computation
}
}
Подход Scala намного лучше, потому что:
- Кэширование вряд ли будет широко распространено.Например, маловероятно, что все методы в классе или все открытые методы во всех классах в пакете кэшируются.И даже если есть такая ситуация,
keyScript
вряд ли будет таким же или легко выразимым в общей форме. - Подход AspectJ использует аннотацию в качестве опоры, чтобы предложить достойную реализацию.С помощью функции высшего порядка в Scala намерение выражается напрямую.
- Подход AspectJ должен использовать внешний язык (такой как OGNL или Spring Expression Language) для вычисления ключа.В Scala вы можете просто использовать язык хоста.
В середине распространены общие проблемы управления транзакциями и безопасности.На первый взгляд, они очень похожи на кеширование.Однако на практике мы находим, что применение этих функций ко всем методам класса (с общим подвыбором, например, с открытым доступом) или ко всем методам всех классов, помеченных аннотацией (скажем, @Service
), является распространенным явлением.Если это так, то подход AspectJ в конечном итоге превосходит, поскольку он предоставляет способ применить функциональность на более высоком уровне, чем функции более высокого порядка.Вам больше не нужно окружать каждый метод transactional {}
или secured {}
, когда аннотация на уровне класса будет работать нормально.Применительно к проблемам безопасности подход AspectJ позволяет упростить аудит безопасности.
На другом конце спектра - это общие задачи, такие как трассировка, профилирование, мониторинг, применение политик,аудит, некоторые формы управления параллелизмом (такие как диспетчеризация потоков Swing / SWT / Android) и т. д. Они очень хорошо подходят для выбора с помощью pointcut (с аннотациями и часто без них).Очень трудно сделать то же самое согласованным образом, используя только функции более высокого порядка.
Существует больше семантических нюансов, но суть в том, что, когда вы обнаружите, что для каждого метода применяется аннотирование с применением сквозной задачи,функция более высокого порядка, вероятно, будет лучшим подходом.Для других использование Scala с AspectJ, вероятно, обеспечит согласованное и компактное решение.
ps Я не пробовал AspectJ + Scala в Eclipse в последнее время (так как Scala в Eclipse начал работать только недавно).Но внешняя сборка с использованием Maven работала нормально после исправления http://lampsvn.epfl.ch/trac/scala/ticket/4214.