2010-05-15 17 views
5

Esto puede ser una pregunta bastante subjetiva, pero tal vez no. Mi aplicación contiene un montón de formularios que se muestran al usuario en diferentes momentos. Cada forma es una clase propia. Normalmente, el usuario hace clic en un botón, que inicia un nuevo formulario.Adecuación de la reflexión de Java

que tienen una función de conveniencia que construye estos botones, se llaman así:

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

hago esto docenas de veces, y es muy engorroso tener que hacer un SelectionAdapter cada vez.

Realmente todo lo que necesito para el botón saber es qué clase instanciar cuando se hace clic en él y qué argumentos para dar el constructor, por lo que construyó una función que llamo esta forma:

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

Donde args es una lista arbitraria de objetos que podría usar para crear instancias de TasksForm normalmente.

Utiliza la reflexión para obtener un constructor de la clase, coincide con la lista de argumentos y crea una instancia cuando es necesario. La mayoría de las veces no tengo que pasar ningún argumento al constructor en absoluto. El inconveniente es, obviamente, que si paso un conjunto de argumentos incorrecto, no puede detectarlo en el momento de la compilación, por lo que si falla, se muestra un diálogo en tiempo de ejecución. Pero normalmente no fallará, y será fácil de depurar si lo hace.

Creo que esto es mucho más limpio porque vengo de idiomas donde el uso de literales de función y clase es bastante común. Pero si usted es un programador Java normal, ¿le daría miedo verlo o le agradecería no tener que escanear un trillón de SelectionAdapters?

+0

I'd go with reflection. –

Respuesta

3

Sí, normalmente la reflexión no está bien, pero en algunos casos puede ser bastante útil. Agradecería leer el código que puedo digerir bastante rápido sin tener que pasar por un trillón de cosas pequeñas.

0

El problema no es la reflexión per se. Los marcos modernos usan la reflexión todo el tiempo. Y es genial usar anotaciones para hacer todo tipo de cosas, lo que generalmente requiere reflexión.

Sin embargo, en su caso, ¿Por qué no acaba de hacer:

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

a menos que su clase anónima está utilizando variables finales del ámbito de aplicación, no veo ninguna razón.

+0

Si te entiendo correctamente, estás sugiriendo que no uses clases anónimas, en cuyo caso tendría que crear una implementación de SelectionAdapter para cada clase que quisiera crear una instancia. Desafortunadamente, tengo docenas de ellos (TasksForm fue solo un ejemplo.) Parece más abarrotado para mí, pero tal vez estoy malentendido. – jsn

+0

Ok, tienes razón. Vaya con la reflexión o pase el objeto TaskForm en su lugar. – Artefacto

+0

He editado la publicación en consecuencia. – Artefacto

0

Has modificado tu buildButton(String, SelectionAdapter) para tomar una clase en la que reflexionarás. Supongo que ahora está creando un nuevo SelectionAdapter en su método modificado y luego está reflexionando sobre el nombre de clase, creando una instancia y pasándola al showForm(arg). Creo que esto es un paso más de lo que necesitas.

En su lugar, puede hacer que tome una instancia de cualquier clase que su showForm(arg) requiera. La clave será hacer ese argumento final en su arglist para buildButton, y podrá usarlo en su clase anónima.

+1

Como el formulario es un componente de la interfaz de usuario, no puedo crear una instancia cuando construyo el botón, tengo que esperar hasta que se haga clic en el botón, de ahí el SelectionAdapter – jsn

0

Una forma alternativa es tener un método estático en cada formulario que devuelve un botón que crea el formulario. Pero la reflexión probablemente sería mejor.

1

Si entiendo correctamente, desea ejecutar una operación (createButton) con diferentes tipos de implementaciones de botón (formularios) para el argumento. Esto suena exactamente como si necesitaras polimorfismo.

Le sugiero que se olvide de la reflexión y construya estos formularios en una interfaz común. Digamos interface Form { //some methods here }

Todos los formularios tendrán que implementar la interfaz común y se requiere de estos métodos para la creación del botón. Así que si usted tiene un objeto Form, puede pasar a la createButton(Form formObject){...}

si todos SelectionAdapter hace es llamar a un método showForm, puede agregarlo a la común interface Form y simplemente invocar este método para un objeto Form. Por lo tanto, no es necesario crear muchas clases anónimas, sino solo una y crear instancias con un objeto "Formulario".

Así que todo lo que necesita es el polimorfismo y las interfaces elegidas para estas clases.

Si tiene un gran problema con la creación de los objetos Form (sus constructores son diferentes), puede considerar la creación de un MyFormBuilder que maneje solo la construcción. El constructor tendrá el método createInstance() o el método getInstance() que hará todo el trabajo.

Con mi sugerencia, tendrá 1 implementación de clase SelectionAdapter, pasará objetos con una interfaz común y habrá evitado la reflexión, pasando los argumentos de MyClass.class, etc.

Cuestiones relacionadas