Уместность отражения Java - PullRequest
5 голосов
/ 15 мая 2010

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

У меня есть удобная функция, которая создает эти кнопки, вы называете это так:

buildButton( "button text", new SelectionAdapter() {
     @Override
     public void widgetSelected( SelectionEvent e ) {
        showForm( new TasksForm( args... ) );
     }
  } );

Я делаю это десятки раз, и это действительно обременительно - каждый раз создавать SelectionAdapter.

На самом деле все, что мне нужно, чтобы кнопка знала, это то, какой класс нужно создавать при нажатии и какие аргументы передать конструктору, поэтому вместо этого я создал функцию, которую я вызываю так:

buildButton( "button text", TasksForm.class, args... );

Где args - произвольный список объектов, которые вы можете использовать для создания экземпляра TasksForm в обычном режиме.

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

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

Ответы [ 5 ]

3 голосов
/ 15 мая 2010

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

1 голос
/ 16 мая 2010

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

Я предлагаю вам забыть об отражении и сконструировать эти формы под общим интерфейсом. Скажем interface Form { //some methods here }

Все ваши формы должны будут реализовывать общий интерфейс, и эти методы необходимы для создания кнопки. Поэтому, если у вас есть объект Form, вы можете передать его в createButton(Form formObject){...}

Если все SelectionAdapter вызывает метод showForm, вы можете добавить его к общему interface Form и просто вызвать этот метод для объекта Form. Таким образом, вам не нужно создавать много анонимных классов, а только один и создавать его с помощью объекта «Форма».

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

Если у вас есть большие проблемы с созданием объектов Form (их конструкторы различаются), возможно, вам следует подумать о создании MyFormBuilder, который обрабатывает только конструкцию. У строителя будет метод createInstance() или метод getInstance(), который будет выполнять всю работу.

По моему предложению у вас будет 1 реализация класса SelectionAdapter, вы будете передавать объекты с общим интерфейсом и избегать отражения, передавая аргументы MyClass.class и т. Д.

0 голосов
/ 15 мая 2010

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

0 голосов
/ 15 мая 2010

Вы изменили свой buildButton(String, SelectionAdapter), чтобы принять класс, который вы будете отражать.Я понял, что вы сейчас создаете новый SelectionAdapter в своем измененном методе, а затем размышляете над именем класса, создаете экземпляр и передаете его в showForm(arg).Я думаю, что это на шаг дальше, чем нужно.

Вместо этого вы можете получить экземпляр любого класса, который требуется вашему showForm(arg).Ключ будет заключаться в том, чтобы сделать аргумент final в вашем арглисте для buildButton, и вы сможете использовать его в своем анонимном классе.

0 голосов
/ 15 мая 2010

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

Однако, в вашем случае, почему бы вам просто не сделать:

buildButton( "button text",
        new SelectionAdapterImplementation(new TaskForm(args)) )

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

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