2011-02-02 8 views
7

Siempre he querido escribir un mundo simple en Java, pero que luego podía ejecutar el 'mundo' y luego agregar nuevos objetos (que no funcionaban) existe en el momento en que el mundo comenzó a correr) en una fecha posterior (para simular/observar diferentes comportamientos entre objetos futuros).necesito diseño/patrón/estructura ayuda en la codificación de un 'mundo' de Java

El problema es que no quiero detenerme ni reiniciar el mundo una vez que se ha iniciado, quiero que se ejecute durante una semana sin tener que recompilarlo, pero tengo la capacidad de colocar objetos y rehacer/reescribir/eliminar/crear/mutar a lo largo del tiempo.

El mundo podría ser tan simple como una matriz de 10 x 10 de x/y 'ubicaciones' (piense en tablero de ajedrez), pero supongo que necesitaría algún tipo de proceso ticktimer para monitorear objetos y darles a cada uno (si hubiera) oportunidad de 'actuar' (si lo desean).

Ejemplo: Codigo World.java el lunes y lo dejo en funcionamiento. Luego, el martes, escribo una nueva clase llamada Rock.java (que no se mueve). Luego lo dejo (de alguna manera) en este mundo que ya funciona (que simplemente lo deja en algún lugar aleatorio en la matriz de 10x10 y nunca se mueve).

Luego, el miércoles creo una nueva clase llamada Cat.java y la dejo caer al mundo, nuevamente colocada al azar, pero este nuevo objeto puede moverse alrededor del mundo (en una unidad de tiempo), luego el jueves escribo una clase llamada Dog.java que también se mueve pero puede 'actuar' en otro objeto si está en la ubicación vecina y viceversa.

Aquí está la cosa. No sé qué clase de estructura/diseño necesitaría para codificar la clase mundial real para saber cómo detectar/cargar/rastrear objetos futuros.

¿Alguna idea de cómo harías algo como esto?

+2

¡Huelo un barro en la fabricación! – Orbit

+0

¿Hay alguna posibilidad de que deba volver a soltar la misma clase (modificada)? ¿O solo vas a perder nuevas clases? – cherouvim

+0

inicialmente, estaba pensando en nuevas clases, pero sin duda si veo que un objeto existente se está volviendo un poco loco, entonces sí, me gustaría modificarlo (y todas sus instancias) y luego volver a introducirlo en el mundo para observar su comportamiento para otro semana más o menos. – d33j

Respuesta

0

Si sólo se preocupan por la adición de clases (y no modificar) aquí es lo que haría:

  • existe una interfaz Entity con todos los métodos de negocio que necesita (insertIntoWorld(), isMovable(), getName(), getIcon() etc.)
  • hay un paquete específico donde residen las entidades
  • hay un trabajo programado en su aplicación que cada 30 segundos se enumeran los archivos de clases del paquete
  • realizar un seguimiento de las clases y para cualquier nuevo intento de clase para cargar la clase y emitir a Entity
  • para cualquier Entity recién cargado crear una nueva instancia y llamar a insertIntoWorld().

También puede omitir el programador y el descubrimiento automático y tener un control de IU en el World desde donde puede especificar el nombre de clase que se cargará.

Algunos problemas:

  • no se puede actualizar fácilmente un Entity.Que lo más probable que tenga que hacer un poco de magia cargador de clases
  • no se puede ampliar la interfaz Entity añadir nueva bethod negocio, por lo que están obligados a contrato que inicialmente comenzó su aplicación con
1

No sé si hay un patrón/estrategia para un problema como este, pero así es como me acercaría a él:

Me gustaría que todas estas clases diferentes que planea hacer sean objetos de una clase común (tal vez una clase WorldObject) y luego poner sus características diferenciadoras en archivos de configuración separados.

Creación
Cuando el programa se está ejecutando, se comprobaría que rutinariamente carpeta de configuración para los nuevos artículos. Si ve que existe un nuevo archivo de configuración (digamos Cat.config), entonces creará un nuevo objeto WorldObject y le otorgará las características que lee del archivo Cat.config y colocará ese nuevo objeto en el mundo.

Mutación
Si el programa detecta que uno de los archivos de configuración de estos artículo ha cambiado, entonces es encontrar ese objeto en el mundo, editar sus características y la vuelve a visualizar la misma.

Supresión
Cuando el programa busca en la carpeta y ve que el archivo de configuración ya no existe, entonces se elimina el objeto del mundo y comprobaciones forma en que afecta a todos los otros objetos.

0

Demasiada explicación para un problema demasiado simple. En otras palabras, solo desea realizar una carga de clase dinámica.

Primero, si de alguna manera conoce el nombre de la clase, puede cargarlo usando Class.forName(). Esta es la forma de obtener la clase en sí misma. Luego puede instanciarlo usando Class.newInstance(). Si su clase tiene un constructor predeterminado público, es suficiente. Para más detalles, lee sobre la API de reflexión.

¿Pero cómo pasar el nombre de la nueva clase al programa que ya se está ejecutando? Sugiero 2 formas.

  1. El programa puede realizar el sondeo del archivo predefinido. Cuando desee implementar una nueva clase, debe registrarla, es decir, escribir su nombre en este archivo. Además, esta clase debe estar disponible en classpath de su aplicación.
  2. aplicación puede realizar sondeo de (por ejemplo) directorio especial que contiene archivos jar. Una vez que se detecta el nuevo archivo JAR puede leer su contenido (ver JarInputStream), a continuación, llamar a una instancia nueva clase utilizando ClaasLoader.defineClass(), a continuación, llamar newInstane(), etc.
+0

El OP hizo un gran trabajo describiendo el problema en sus propias palabras. Ningún problema es simple a menos que uno sepa cómo resolverlo. – cherouvim

1

yo no apostaría demasiado en la misma JVM corriendo por siempre . Hay muchas maneras en que esto podría fallar (problemas en la computadora, falta de memoria no ejecutada, problemas de permgen debido a la carga de clases repetida).

En cambio, diseñaría un sistema que pueda mantener de manera confiable el estado de cada objeto involucrado (enfoque más simple: hacer que cada objeto se pueda serializar, pero eso no resolvería realmente los problemas de versiones).

Así que, como primer paso, simplemente implementaría una buena magia de cargador de clases para permitir que los frascos se "caigan" en la simulación mundial que se cargará dinámicamente.Pero una vez que llega a un punto en el que ya no funciona (porque necesita modificar el mundo en sí, o necesita hacer cambios incompatibles con algún objeto), puede persistir en el estado, cambiar las bibliotecas por nuevas versiones y volver a cargar el estado .

Ser capaz de persistir el estado también le permite producir fácilmente escenarios de prueba o reproducir escenarios con diferentes parámetros.

1

Eche un vistazo a OSGi: este marco permite instalar y eliminar paquetes en tiempo de ejecución.

El marco es un contenedor para los llamados paquetes , bibliotecas java con algunos datos de configuración adicionales en el archivo de manifiesto de jar.

Puede instalar un paquete "mundial" y mantenerlo en funcionamiento. Luego, después de un tiempo, instale un paquete que aporte rocas o arena al mundo. Si ya no te gusta, deshabilítalo. Si necesita otras rocas, instale una versión actualizada del mismo paquete y actívela.

Y con OSGi, puede mantener el mundo girando y moviéndose alrededor del sol.

La implementación de referencia es equinox


Por cierto: "No sé qué clase de estructura/diseño" - al menos es necesario definir una interfaz para un "objeto geolocatable", de lo contrario no podrás colocarlo ni mostrarlo. Pero para el "mundo", tal vez sea suficiente saber que "hay algo en las coordenadas x/y/z" y para el espectador del mundo, que este "algo" tiene un método para "mostrarse a sí mismo".

+0

Oh, me gusta esto ... pero el 'mundo' no debería saber sobre' cat' en un momento en que 'cat' aún no existe. De todos modos, +1 – CurtainDog

+0

@CurtainDog - No, no lo haría. El "mundo" no sabe qué es exactamente lo que está mintiendo o rastreando en su superficie (= mundo ** tiene-una ** superficie). Puede saber, qué ubicación (coordenada) está ocupada por * algo *. Y el espectador del mundo puede pedirle * algo * que se dibuje en la proyección 2D (o 3D). –

0

Lo que básicamente está creando aquí se llama contenedor de aplicaciones. Afortunadamente, no hay necesidad de reinventar la rueda, ya hay grandes piezas de software que están diseñadas para seguir funcionando durante largos períodos de tiempo ejecutando código que puede cambiar con el tiempo. Mi consejo sería elegir primero tu IDE, y eso te llevará de alguna manera a qué contenedor de aplicaciones deberías usar (algunos están mejor integrados que otros).

necesita una capa de persistencia, la JVM es confiable pero eventualmente alguien tropezará con el cable de alimentación y borrará su mundo. De nuevo con JPA et al. no hay necesidad de reinventar la rueda aquí tampoco. Hibernate es probablemente el "estándar", pero con sus requisitos probaría algo un poco más elegante con una de las soluciones NoSQL basadas en gráficos.

0

lo que probablemente quiera echarle un vistazo, es el patrón/enfoque de "modelo de objetos dinámicos". Lo implementé hace algún tiempo. Con él puede crear/modificar tipos de objeto en tiempo de ejecución que son una especie de plantillas para objetos. Aquí es un documento que describe la idea:

http://hillside.net/plop/plop2k/proceedings/Riehle/Riehle.pdf

hay más documentos, pero no fue capaz de publicarlos, porque esta es mi primera respuesta y no tengo la reputación suficiente. Pero Google es tu amigo :-)

Cuestiones relacionadas