Вопрос по java, refactoring, language-agnostic, reflection – Java Reflection и боль в рефакторинге

10

Отражение Java предоставляет механизм для самоанализа объекта во время выполнения. Не задумываясь, это отличная функция, но она нарушает все соглашения по рефакторингу!

Там нет простого пути (кромеFile Searchдаже в современных IDE знать, на какой атрибут ссылаются и где. Это делает Refactorings намного более сложным (утомительным!) И подверженным ошибкам.

Откровенно говоря, это не простоReflection API; Hibernate mapping files (hbm.xml) а такжеJSP files оба ссылаются на атрибуты как на String, и когда вы реорганизуете имя атрибута, вам придется вручную изменить все эти места.

Хуже того, изменения в файлах отображения Hibernate или файлах JSP приводят к ошибкам во время выполнения.

Мне интересно знать, как другие программисты справляются с этим на Java. Есть ли инструменты? Я использую Eclipse / IBM RAD в качестве основной платформы разработки. Обычно мы используемconstant определить атрибут и использовать его всякий раз, когда это возможно, но это не всегда возможно.

Мне также было бы интересно, как другие языки справляются с этим!

В настоящее время IntelliJ обладает довольно хорошими привязками к файлам конфигурации JSP, Spring и Hibernate, которые все «осведомлены о рефакторинге». Я не пользователь Eclipse, но мне показалось, что у него тоже есть что-то похожее. Nick Holt
@Tom: AFAIK Eclipse сам по себе не может, и с помощью дополнительного плагина Hibernate Tools или Spring Tools это было невозможно, кроме поиска по строке. lud0h
также в NetBeans есть несколько интеллектуальных инструментов рефакторинга (весна, web.xml и т. д.) dfa
Используйте коллектор@Jailbreak для типобезопасного отражения. Получите доступ к закрытым полям, методам и т. Д., Позвольте компилятору Java безопасно проверить их использование, и пусть Manifold создаст для вас базовый код отражения. Учить больше:manifold.systems/docs.html#type-safe-reflection Scott
Я думаю, что Eclipse может реорганизовать файлы Hibernate. Tom Hawtin - tackline

Ваш Ответ

9   ответов
0

вас заинтересует использование IntelliJ IDEA, которое также будет искать измененные имена классов в комментариях и строковых константах.

NetBeans (и, вероятно, другие) тоже
Eclipse (и, по-видимому, netbeans) тоже может это сделать, но он по-прежнему не гарантированно работает, так как он будет перехватывать только полностью определенные имена классов.
0

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

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

Но не существует общего решения для прямого «ручного» управления. использование API отражения - вот почему это обычно не рекомендуется.

Поскольку эти файлы имеют четко определенный синтаксис, это по крайней мере возможно (и не слишком сложно).
Проблема не только в Reflection API. Конфигурационные файлы, такие как в Hibernate или JSP, привязаны ко времени компиляции, и инструменты не захватывают их эффективно. lud0h
7

которые возникают у динамически типизированных языков, таких как Python и Ruby. Фактически, один из способов думать о динамически типизированных языках - это то, что все вызывается с использованием рефлексии, а языки просто обеспечивают хороший, чистый синтаксис для рефлексии.

И да, с динамически типизированными языками (или интенсивным использованием рефлексии) рефакторинг сложен. Вы не получаете хороших возможностей рефакторинга Eclipse. Вместо этого grep становится вашим другом.

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

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

Это больше не верно с коллектором. использование@Jailbreak заtype-safe отражение. Получите доступ к закрытым полям, методам и т. Д., Позвольте компилятору Java безопасно проверить их использование, и пусть Manifold создаст для вас базовый код отражения. Учить больше:manifold.systems/docs.html#type-safe-reflection
Фактически, первой IDE, которая реализовала рефакторинг, был Smalltalk, который довольно динамичен. AFAIK инструмент рефакторинга выполнил анализ, отслеживая его выполнение (обычно через модульные тесты) и отслеживая, какие пути используются, какие методы вызываются и т. Д. Рефакторинг динамического кода возможен, но его трудно реализовать и Я полагаю, что это причина, по которой он не является широко доступным в IDE.
2

которая при переименовании класса будет искать полное имя, например, в ваших XML-файлах, чтобы попытаться переименовать любые ссылки, которые могут у вас быть в них. Не думаю, что это решает проблему - очень часто вы не просто ссылаетесь на имена классов.

Кроме того, именно поэтому необходимо проявлять особую осторожность и осмотрительность, прежде чем использовать его в своем собственном коде.

Но эта проблема с размышлениями объясняет, почему использование аннотаций становится все более популярным. Проблема уменьшается при использовании аннотаций.

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

Это с точки зрения постоянства, например. Например, если я использую аннотации, чтобы указать, что класс является постоянным, и переименую этот класс, аннотация останется, и она все еще будет постоянной. Мне не нужно будет искать все случаи, когда класс является ссылками в файлах сопоставления, и также изменять это.
Как аннотации решают проблему в таких сценариях? Можете привести пример? Спасибо. lud0h
2

который в значительной степени решает эту проблему. Это называется RefaFlex: http://www.feu.de/ps/prjs/rf/

0

dp4j.com когда вы знаете во время компиляции, что вы ищете.

Что касается XML-отображений, то это боль, я также испытывал это на платформе NetBeans и меньше на JPA2. Хорошей новостью является то, что аннотации вступают во владение, и это предлагает снова проверку во время компиляции. Я не уверен насчет Hibernate, но как JPA, так и NetBeans (больше по состоянию на 7) предлагать аннотации эквивалентов сопоставлений XML.

Я также разработалSqlWrapper чтобы избежать использования строк с JDBC. Более сложным (и сложным) является API критериев JPA2.

0

методов, полей taggin, к которым вы обращаетесь с помощью рефлексии? IDE может предупредить вас, когда вы меняете их имена.

0

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

Тем не менее, J2EE-версия Eclipse IDE вместе с подходящими плагинами для основных сред, таких как Hibernate, Spring и т. Д., Отлично справится с рефакторингом. Модульные тесты сократят цикл тестирования, но проблема в том, что иногда модульные тесты также зависят от некоторой конфигурации XML, заставляя вас использовать рефлексию. Таким образом, можно выполнить модульные тесты вместе с вашим кодом при рефакторинге.

1

введя больше «литералов» на языке. Например. imho .class literal - отличный способ обеспечить безопасность определенных моделей во время компиляции. Однако важно сказать, что иногдаI want to lose compile-time safety, Строки - это самый простой, но эффективный способ выражения слабосвязанного контракта между двумя уровнями, поскольку вы можете манипулировать ими или сопоставлять их с регулярным выражением и т. Д.

Настоящая проблема рефлексии - многословное использование API. Это основные затраты на гибкость.

PS

Проектная монета могла бы где-то в будущем ввести какую-то новую языковую конструкцию для расширения этой области.

Похожие вопросы