Я прежде всего разработчик Java. Я встретил довольно много разработчиков Java, которые любят АОП. В последнее время я вижу все больше и больше "шаблонов проектирования" АОП, которые, похоже, довольно широко приняты. Тем не менее, я все еще не уверен, что АОП в коде OO - хорошая идея в целом по нескольким причинам.
-
Он добавляет "волшебство" к коду в формы непрозрачной сложности, которая может быть чрезвычайно трудным для отладки и может сделать его чрезвычайно трудным для отладки объектно-ориентированный код, который он влияет.
-
Мне кажется, в основном ненужные и (что еще хуже) часто используются чтобы избежать необходимости хорошо проектировать или для компенсации прежних бедных дизайн.
Вот пример, который я видел много за последние пару лет, в качестве фона для моего вопроса.
До AOP (из документов Hibernate)
public void saveMyEntityToTheDatabase(MyEntity entity) {
EntityTransaction tx = null;
try {
tx = entityManager.getTransaction();
tx.begin();
entityManager.persist(entity);
tx.commit();
} catch (RuntimeException e) {
if(tx != null && tx.isActive()) {
tx.rollback();
}
throw e;
}
}
После AOP
@Transactional
public void saveMyEntityToTheDatabase(MyEntity entity) {
entityManager.persist(entity);
}
Кажется, это очевидная победа для АОП для многих людей. Для меня исходная проблема является симптомом несогласованных уровней абстракции API. То есть, EntityManager
намного ниже, чем API-интерфейс бизнес-уровня сообщения, использующего его. Эта проблема может быть решена с более подходящим уровнем абстракции и лучшим (OO) дизайном.
Решение OO
public void saveMyEntityToTheDatabase(MyEntity entity) {
database.performInTransaction(new Save(entity));
}
Это решение предполагает, что объект database
содержит такую же транзакционную логику, что и тот аспект, который отвечает за методы @Transactional
. Это касается моих проблем выше, сделав более очевидным, что есть что-то, управляющее взаимодействием с EntityManager
, а не введение другой парадигмы программирования.
Итак, наконец, мой вопрос: что может AOP сделать, что ООП не может? Я немного уверен в его полезности в протоколе трассировки и, возможно, по умолчанию toString()
реализациях или чем-то подобном, но мне было бы интересно узнать, сможет ли кто-нибудь найти его значительно лучше, чем OO для определенных типов проблем.