Варианты использования для размышления - PullRequest
19 голосов
/ 08 сентября 2008

Недавно я разговаривал с коллегой по C ++ и посетовал, что не было никакого способа взять строку с именем поля класса и извлечь поле с этим именем; другими словами, в нем не хватает отражения. Он озадаченно посмотрел на меня и спросил, когда кому-нибудь понадобится что-то подобное.

Сверху головы у меня не было хорошего ответа для него, кроме «эй, мне нужно сделать это прямо сейчас». Поэтому я сел и составил список некоторых вещей, которые я фактически сделал с отражением на разных языках. К сожалению, большинство моих примеров взяты из моего веб-программирования на Python, и я надеялся, что у людей здесь будет больше примеров. Вот список, который я придумал:

  1. Имеется файл конфигурации с такими строками, как
    x = "Привет, мир!"
    у = 5,0
    динамически устанавливать поля некоторого объекта config равными значениям в этом файле. (Это было то, что я хотел сделать в C ++, но на самом деле не мог.)

  2. При сортировке списка объектов сортируйте на основе произвольного атрибута, заданного именем этого атрибута, из файла конфигурации или веб-запроса.

  3. При написании программного обеспечения, использующего сетевой протокол, отражение позволяет вам вызывать методы на основе строковых значений из этого протокола. Например, я написал бот IRC, который будет переводить
    !some_command arg1 arg2
    в вызов метода actions.some_command(arg1, arg2) и выведите то, что эта функция вернула обратно в IRC-канал.

  4. При использовании функции Python __getattr__ (которая похожа на method_missing в Ruby / Smalltalk) я работал с классом с большим количеством статистики, такой как late_total. Для каждой статистики я хотел иметь возможность добавить _percent, чтобы получить эту статистику в процентах от общего количества вещей, которые я рассчитывал (например, stats.late_total_percent). Отражение сделало это очень легко.

Так может ли кто-нибудь здесь привести примеры из собственного опыта программирования времен, когда размышления были полезны? В следующий раз, когда сотрудник спросит меня, почему я «когда-нибудь захочу сделать что-то подобное», я бы хотел быть более подготовленным.

Ответы [ 9 ]

16 голосов
/ 08 сентября 2008

Я могу перечислить следующее использование для отражения:

  • Позднее связывание
  • Безопасность (самоанализ кода по соображениям безопасности)
  • Анализ кода
  • Динамическая печать (утка невозможна без отражения)
  • Метапрограммирование

Некоторые реальные примеры отражения моего личного опыта:

  • Разработанная система плагинов на основе отражения
  • Используемая модель аспектно-ориентированного программирования
  • Выполнен статический анализ кода
  • Используются различные рамки для внедрения зависимостей
  • ...

Отражение это хорошая вещь:)

4 голосов
/ 08 сентября 2008

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

string src = MethodInfo.GetCurrentMethod().ToString();
string msg = "Big Mistake";
Exception newEx = new Exception(msg, ex);
newEx.Source = src;

вместо

string src = "MyMethod";
string msg = "Big MistakeA";
Exception newEx = new Exception(msg, ex);
newEx.Source = src;

Это просто для копирования / вставки наследования и генерации кода.

3 голосов
/ 08 сентября 2008

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

2 голосов
/ 08 сентября 2008

Я нахожу отражение очень полезным, если входные данные (например, xml) имеют сложную структуру, которая легко сопоставляется с объектами-экземплярами, или мне нужны какие-то отношения "is" между экземплярами.

Поскольку отражение в java относительно легко, я иногда использую его для простых данных (карты значений ключей), где у меня есть небольшой фиксированный набор ключей. С одной стороны, легко определить, является ли ключ действительным (если класс имеет сеттер setKey (String data)), с другой стороны, я могу изменить тип (текстовых) входных данных и скрыть преобразование (например, простое приведение int в getKey ()), поэтому остальная часть приложения может полагаться на правильно введенные данные. Если тип некоторой пары ключ-значение изменяется для одного объекта (например, от формы int до float), мне нужно только изменить его в объекте данных и его пользователях, но не нужно также учитывать проверку парсера. , Это не может быть разумным подходом, если производительность является проблемой ...

2 голосов
/ 08 сентября 2008

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

Если я подумаю немного дольше, я, вероятно, смогу придумать больше примеров.

1 голос
/ 21 сентября 2008

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

Однако есть способ делать то, что вы хотите (ред.). Используйте хеш-таблицу. Сохраните поля, введенные с именем поля.

Если вы действительно хотите, вы можете создать стандартные функции Get / Set или макросы, которые делают это на лету. #define GetX() Get("X") такие вещи.

Вы могли бы даже реализовать свое собственное несовершенное отражение таким образом.

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

1 голос
/ 08 сентября 2008

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

1 голос
/ 08 сентября 2008

Я использовал отражение в C #, когда в фреймворке или сторонней библиотеке, к которой я хотел получить доступ, был какой-то внутренний или закрытый метод.

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

1 голос
/ 08 сентября 2008

Написание диспетчеров. Twisted использует отражающие возможности python для отправки вызовов XML-RPC и SOAP. RMI использует Java Api Reflection для отправки.

Разбор командной строки. Создание объекта конфигурации на основе параметров командной строки, которые передаются.

При написании модульных тестов может быть полезно использовать рефлексию, хотя в основном я использовал это для обхода модификаторов доступа (Java).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...