Что такое точно Отражение и когда это - хороший подход?

Вам необходимо добавить файлы .jar в папку lib $TOMCAT/webapps/$YOUR_WEB_APP/WEB-INF/lib/

.
17
задан JPCosta 14 May 2009 в 16:22
поделиться

10 ответов

Отражение - это средство, с помощью которого вы можете запросить объект о его атрибутах во время выполнения. Например, в Python, Java и .Net есть средства, с помощью которых вы можете найти переменные экземпляра или методы объекта.

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

В качестве простого примера я буду использовать Python, потому что его средства отражения очень просты в использовании и включают меньше шаблонов чем у java или .Net.

ActivePython 2.5.2.2 (ActiveState Software Inc.) based on
Python 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class foo:
...     def __init__(self):
...             self.x = 1
...
>>> xx = foo()      # Creates an object and runs the constructor
>>> xx.__dict__     # System metadata about the object
{'x': 1}
>>> a = xx.__dict__ # Now we manipulate the object through 
>>> a['y'] = 2      # its metadata ...
>>> print xx.y      # ... and suddenly it has a new instance variable
2                   
>>>

Теперь мы использовали базовое отражение для проверки переменных экземпляра произвольного объекта. Специальная переменная __ dict __ в Python - это системное свойство объекта, имеющего хэш-таблицу его членов, ключ к которой определяется именем переменной (или метода). Мы рефлексивно исследовали объект и использовали средства отражения, чтобы искусственно вставить в него вторую переменную экземпляра, которую мы затем можем отобразить, вызвав ее как переменную экземпляра.

Обратите внимание, что этот конкретный трюк не работает на Java или. Net, поскольку переменные экземпляра фиксированы. Система типов этих языков не позволяет добавлять новые переменные экземпляра во время выполнения, как это делает система типизации «утка» в Python. Однако вы могли бы рефлексивно обновить значение переменной экземпляра, объявленной в определении типа.

Вы также можете использовать отражение для динамического создания вызовов методов и выполнения различных других хитростей, таких как создание экземпляра объекта на основе параметра. Например, если у вас была какая-то система на основе подключаемых модулей, в которой определенные возможности были необязательными, вы могли бы использовать отражение, чтобы запросить подключаемый модуль о том, какие услуги он предлагает (возможно, путем запроса, были ли реализованы определенные интерфейсы), не требуя явных метаданных.

Многие динамические языковые интерфейсы, такие как автоматизация OLE, используют отражение как неотъемлемую часть интерфейса.

24
ответ дан 30 November 2019 в 10:19
поделиться

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

Возьмем, к примеру, фреймворки для модульного тестирования. Класс средства выполнения тестов, который отвечает за выполнение всех ваших модульных тестов, заранее не знает, как вы собираетесь называть свои методы. Все, что ему известно, это то, что они будут иметь префикс "test" (или, в случае Java 5, аннотировать @Test ). Поэтому, когда ему предоставляется тестовый класс, он отражает этот класс, чтобы получить список всех методов в нем. Затем он перебирает имена этих методов в виде строк и вызывает эти методы для объекта, если они начинаются с «test». Это было бы невозможно без размышлений. И это всего лишь один пример.

3
ответ дан 30 November 2019 в 10:19
поделиться

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

Возьмем, к примеру, фреймворки для модульного тестирования. Класс средства выполнения тестов, который отвечает за выполнение всех ваших модульных тестов, заранее не знает, как вы собираетесь называть свои методы. Все, что он знает, - это то, что они будут иметь префикс "test" (или, в случае Java 5, аннотировать @Test ). Поэтому, когда ему предоставляется тестовый класс, он отражает этот класс, чтобы получить список всех методов в нем. Затем он перебирает имена этих методов в виде строк и вызывает эти методы для объекта, если они начинаются с «test». Это было бы невозможно без размышлений. И это всего лишь один пример. s Щелкните событие (если у вас включено автоматическое подключение)

Это хорошая идея? Хорошо, только когда альтернативы болезненны. Я предпочитаю статическую типизацию, когда она не мешает - тогда вы получите много хорошего во время компиляции, и это тоже быстрее. Но когда вы действительно нуждаетесь в этом, отражение позволяет делать разные вещи, которые иначе были бы невозможны.

20
ответ дан 30 November 2019 в 10:19
поделиться

Другой пример: у меня есть код, который я использую, который принимает выходные данные из базы данных - который представляет собой набор строк с именованными столбцами - и передает его в массив объектов. Я перебираю строки и, если у целевого объекта есть свойство с тем же именем и типом, я устанавливаю его. В результате мой код получения данных выглядит примерно так:

SqlDataReader sdr = Helper.GetReader("GetClientByID", ClientID);
Client c = new Client();
FillObject(sdr, c);
return c;
2
ответ дан 30 November 2019 в 10:19
поделиться

Рефлексия пригодилась мне как минимум в одном проекте, о котором я могу думать. Мы написали внутреннюю программу «Диспетчер процессов», которая выполняет множество ключевых бизнес-процессов через определенные промежутки времени. Проект настроен таким образом, что ядро ​​на самом деле представляет собой просто службу Windows с объектами таймера, которые запускаются каждые 30 секунд или около того и проверяют, что нужно сделать.

Фактическая работа выполняется в библиотеке классов (соответственно называемой " WorkerLib "). Мы определяем классы с общедоступными методами, которые выполняют определенные задачи (перемещение файлов, загрузка данных на удаленные сайты и т. Д.). Идея состоит в том, что основная служба может вызывать методы из рабочей библиотеки, ничего не зная о методах, которые она вызывает. Это позволяет нам создавать расписание в базе данных для заданий, и даже добавлять новые методы в библиотеку классов без необходимости изменять основную систему.

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

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

на практике довольно аккуратно. Наша основная служба надежна и обрабатывает выполнение заданий по мере необходимости, в то время как фактическая рабочая библиотека может быть расширена и изменена по мере необходимости, даже если ядро ​​даже не заботится.

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

на практике довольно аккуратно. Наша основная служба надежна и обрабатывает выполнение заданий по мере необходимости, в то время как фактическая рабочая библиотека может быть расширена и изменена по мере необходимости, даже если ядро ​​даже не заботится.

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

3
ответ дан 30 November 2019 в 10:19
поделиться

Отражение полезно для конфигурации во время выполнения, позволяя управлять частями системы через внешнюю конфигурацию.

Например, фабрика классов может создавать различные конкретные типы на основе входного файла, где конкретные типы требуют различной информации о конфигурации для вызова конкретного конструктора, а не с использованием интерфейса построителя. (Метод конструктора объекта, размещаемого с помощью отражения).

1
ответ дан 30 November 2019 в 10:19
поделиться

В Java это, по сути, способ создания экземпляра класса, не зная об этом заранее. Допустим, вы хотите, чтобы пользователь мог изменять файл конфигурации, добавляя класс, который он хочет использовать в вашей программе (скажем, у вас есть множество реализаций некоторого интерфейса). С помощью отражения вы можете создать объект, основываясь только на его имени, сигнатуре метода и т. Д. , а затем передайте его в свой интерфейс.

1
ответ дан 30 November 2019 в 10:19
поделиться

На самом деле отражение следует рассматривать как своего рода усилитель кода. Это может сделать хороший код лучше и чище, а плохой - хуже. Что оно делает? Это действительно позволяет вам писать код, при этом вы не совсем уверены, что он будет делать, когда вы его пишете. У вас есть общее представление, но оно позволяет вам не указывать, какие объекты, методы и свойства будут выполняться при компиляции программы.

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

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

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

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

2
ответ дан 30 November 2019 в 10:19
поделиться

Я дам вам пример.

В качестве упражнения по программированию я написал программу проверки файлов mp3. Он сканирует мою музыкальную библиотеку и отображает теги id1 / id2, которые меня интересуют в DataGridView. Я использую отражение, чтобы получить свойства из класса информации mp3, при этом пользовательский код не должен ничего знать об этом классе. Если я хочу изменить отображаемую информацию, я могу либо отредактировать класс информации mp3, либо изменить его конфигурацию (в зависимости от того, как я написал класс), и мне не нужно обновлять пользовательский интерфейс.

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

1
ответ дан 30 November 2019 в 10:19
поделиться

Отражение - это (в основном) способность программы запрашивать информацию о типе, которая была доступна компилятору. Так, например, по имени типа вы можете запросить методы, которые он содержит. Затем для каждого метода вы можете запросить типы принимаемых параметров и т. Д. И т. Д.

Это полезно для конфигурации времени выполнения, когда у вас есть файл конфигурации, который определяет поведение вашего приложения. Конфигурация может содержать имена конкретных типов, которые вы должны использовать (как это часто бывает с контейнерами IOC). Используя отражение, вы можете создать экземпляр этого конкретного типа (через API отражения) и использовать его.

1
ответ дан 30 November 2019 в 10:19
поделиться
Другие вопросы по тегам:

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