Java Dinámico

Estoy realizando una aplicación en Java y he llegado a una encrucijada.
Escenario
La aplicación que estoy realizando recibe llamados desde otros sistemas o aplicaciones con un Id de Programa o Función en particular, se programa la acción para cada función o programa. Estas acciones son diferentes por función Replicar en una base de datos, enviar un e-mail u otras cosas.
Todo está bien se compila y funciona.
Lo ideal es que sea dinámica el llamado de la acción final.
Actual
Función_A --> Modelo --> Controlador_A
Función_B --> Modelo --> Controlador_B
Función_C --> Modelo --> Controlador_C
Necesidad
Función_A --> Modelo --> Controlador_Dinamico_A
Función_B --> Modelo --> Controlador_Dinamico_B
Función_C --> Modelo --> Controlador_Dinamico_C
Parte de la Idea es crear la clases y colocarlas en algún lugar donde puedan ser leídas y compiladas con el mismo código sin necesidad de modificar el programa del Modelo.
No tengo idea de cómo realizar esto en Java y si se puede, por eso recurro a ustedes por alguna sugerencia.
Respuesta
1
Me parece interesante lo que estas haciendo... existen muchas formas de hacer eso en Java... te hago una pregunta... tus controladores son instancias de una misma clase a la que le modificas ciertos atributos de acuerdo a la función que desear realizar, ¿o cada controlador es una clase diferente?
Tengo un método handleRequest por para todas la funciones.
Dentro de este método quisiera:
    Detectar que función es (Resuelto).
    Invocar la Clase (ClaseDinamica) que va a manejar los valores enviados Por Cada Función(No Resuelto).
Retornar el Resultado de la ClaseDinamica al handleRequest para que responda al sistema Origen.
Esta aplicación es como un administrador de servicios.
Idea 1. lo que se puede hacer es que cuando suba compile las ClasesDinamicas nuevas para que estén disponibles, lo que no quisiera es tener que editar la clase del método handleRequest.
Se podría recompilar el Proyecto, podría ser una Opción.
Idea 2. Es que lea las clasesdinamicas en tiempo de ejecución, No se que tan optimo seria.
Normalmente creo un objeto
Clase objNuevo = new Clase
Como podría hacer esto dinamico por ejemplo
("clasedinamica001") objfunción = new ("clasedinamica001");
Objfunción.ejecutar (parametrosentrada, parametrossalida);
Esto no se como hacerlo.
Ok, bueno lo que quieres hacer se conoce como "Reflexion" y es una de las cosas más avanzadas y poderosas de la programación orientada a objetos... no es para subestimarte pero esto es complicado y si no sabes usarlo se puede convertir en un dolor de cabeza... Se recomienda el uso de la reflexión como ultimo recurso, es decir cuando es imposible hacer algo de otra forma... Otra cosa que debes tener en cuenta es que la reflexión carga definiciones de clases dinámicamente y por lo tanto, las operaciones reflectivas tienden a enlentecer el sistema, por lo tanto no se recomienda su uso en puntos del programa que son ejecutados con alta frecuencia, pues podría perjudicar notoriamente el rendimiento de tu aplicación... Y Por ultimo la reflexión permite al código realizar operaciones que serian ilegales en código-no reflectivo, tales como acceder atributos y métodos privados lo cual podría traer comportamiento o resultados inesperados por lo tanto debe usarse con mucho cuidado... si después de todo lo que te he dicho encuentras que estas cosas no afectaran tu programa, entonces si puedes usar la reflexión... he preparado un ejemplo para que veas como se usa:
//esta clase es la invocaremos usando reflexion
public class MyClaseDesconocida {
private int atributoPrivado;
public int getAtributoPrivado(){
return atributoPrivado;
}
public void setAtributoPrivado( int valor ){
atributoPrivado = valor;
}
public void mostrarAtributoPrivado(){
System.out.println("atributoPrivado: "+ atributoPrivado);
}
public void myMetodo(String mensaje){
System.out.println("Mensaje impreso desde MyClaseDesconocida.myMetodo: "+mensaje);
}
}
// y esta otra clase es la que ejecuta el ejemplo
import java.lang.reflect.*;
public class EjemploReflexion {
public static void main(String args []){
try {
// cargamos la clase
Class clase = Class.forName("MyClaseDesconocida");
// creamos una instancia de nuestra clase desconocida
Object instanciaDeClaseDesconocida = clase.newInstance();
// creamos un metodo indicando el nombre del metodo y los parametros
// que recibe
Method metodo = clase.getMethod("myMetodo",String.class);
// invocamos el metodo
metodo.invoke(instanciaDeClaseDesconocida,"Hola mundo!");
// hacemos los mismo con este otro metodo que recibe un entero por parametro
metodo = clase.getMethod("setAtributoPrivado",int.class);
// invocamos el metodo mandandole un 7 por parametro
metodo.invoke(instanciaDeClaseDesconocida,7);
// creamos otro metodo para ver el atributo de nuestra instancia
metodo = clase.getMethod("mostrarAtributoPrivado");
// invocamos el metodo... notese que no recibe parametros
metodo.invoke(instanciaDeClaseDesconocida);
// este metodo devuelve el atributo privado de nuestra instancia
metodo = clase.getMethod("getAtributoPrivado");
// obtenemos el atributo privado invocando el metodo
Object res = metodo.invoke(instanciaDeClaseDesconocida);
// mostramos la respuesta de nuestro metodo
System.out.println("Este es el atributo privado de tipo '"+res.getClass().getName()+"' devuelto por mi metodo getAtributoPrivado(): "+res);
}
catch(ClassNotFoundException ex){
System.out.println("La clase no pudo ser encontrada");
}
catch (InstantiationException x) {
System.out.println("No se pudo crear una instancia de la clase desconocida");
}
catch (IllegalAccessException x) {
System.out.println("No se puede tener acceso a la clase desconocida");
}
catch(IllegalArgumentException x){
System.out.println("Los argumentos para invocar al metodo no son correctos");
}
catch(InvocationTargetException x){
System.out.println("El metodo invocado lanzo una excepcion");
}
catch (NoSuchMethodException x) {
System.out.println("El metodo no pudo ser encontrado");
}
}
}
Bueno eso es todo... espero que te sirva mi respuesta... suerte!
Esta buenísima la explicación y la entendí bien, te tengo unas últimas preguntas.
1. La clase desconocida donde la colocaría para que la pueda ver el programa
2. Mi aplicación es para que este constantemente en uso, por lo que el acceso es muy frecuente, si leo dinámicamente cada vez que lo necesite será lento. La incorporación de nuevos programas no es frecuente crees que es preferible recompilar la aplicación.
Gracias de antemano por las respuestas.
Respuesta 1) No importa donde este tu clase desconocida... en mi ejemplo las dos clases están en el mismo folder por eso es que basta con colocar el nombre de la clase... pero si estas usando paquetes (package) puedes especificar el nombre del paquete y la clase así:
Ejemplo:
package com.alejosoft.util;
public class Desconocida { .... }
//-----------> En la otra clase:
public class Ejemplo {
public static void main(String args[]){
     Class clase = Class.forName("com.alejosoft.util.Desconocida");
     .... lo demas .....
}
}
Respuesta 2) Otra forma de solucionar esto es usando interfaces (interface) puedes crear una interfaz que contenga los métodos o atributos comunes entre tus controladores y hacer que todos tus controladores, y cualquier otro nuevo que quieras agregar, implementen esa interface y de esa forma en tu método handleRequest llamaría a ese método general de cada implementación de tu interface sin importarle que clase lo esta implementando... Si no conoces el uso de interfaces te podría explicar, es bien sencillo... pero esa respuesta estaría fuera del contexto de esta pregunta, así que tendrías que crear otra pregunta acerca de como usar interfaces en java... ademas creo que hasta este punto seria justo que finalices esta pregunta :D ...

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas