2011-08-06 15 views
5

Actualmente estoy trabajando en un proyecto en el que tenemos que representar un conjunto de vectores en un entorno 3D. Tenemos varias implementaciones de visualización diferentes.Uso de enumeraciones como contenedor de implementaciones

Llegué a la idea de que podía agrupar todos los tipos de visualización en una enumeración. He definido una interfaz VectorVisualization y varias implementaciones que implementan esta interfaz.

Ahora he añadido a la clase de interfaz de la siguiente enumeración:

public interface VectorVisualization { 

    public enum VectorVisualizationType { 
     CYLINDER(new VectorVisualizationCylinder(), "Cylinder"), 
     CONES(new VectorVisualizationCones(), "Cones"), 
     FATCONES(new VectorVisualizationFatCones(), "Fat cones"), 
     ARROWS(new VectorVisualizationArrows(), "Arrows"); 

     private final String label; 
     private final VectorVisualization vis; 

     VectorVisualizationType(VectorVisualization vis, String label) { 
      this.vis = vis; 
      this.label = label; 
     } 

     public VectorVisualization getVisualization() { 
      return this.vis; 
     } 

     public String getLabel() { 
      return this.label; 
     } 
    } 

    void prepareVBO(GL gl, ArrayList<VectorData> vectors, VectorField field); 
    void render(GL gl); 
    void clearOldVBOS(GL gl); 
} 

La etiqueta es para un JComboBox en la GUI. Así que ahora puedo simplemente iterar sobre la enumeración y obtener la etiqueta de los diferentes tipos. También para establecer una Implementación puedo usar la enumeración de esa manera:

VectorVisualizationType.CYLINDER.getVisualization() 

¿Pero esta es una buena manera? ¿O hay algún problema con ese enfoque? Por supuesto, ahora que ha creado una nueva implementación, debe agregar esto a la enumeración.

¡Gracias por su opinión!

Respuesta

1

Interesante. He usado tipos enumerados para transportar bits útiles de metadatos antes, pero nunca lo tomé tan lejos como para almacenar fragmentos de código ejecutable.

Dicho esto, el único problema que veo con su enfoque es que, como ya ha notado, cuando cree una nueva implementación VectorVisualization, tendrá que agregar manualmente una nueva entrada a la enumeración. En general, prefiero evitar tal sobrecarga manual siempre que sea posible, pero en realidad esa es una cuestión de preferencia personal.

Si usted (y todos los demás que trabajen en este código con usted) son conscientes de esta limitación y no les importa, entonces creo que su solución está bien.

Tenga en cuenta que su estructura actual requiere que cada VectorVisualization se implemente de forma segura para subprocesos, ya que solo hay una instancia que se distribuye a todos los que hacen referencia al tipo enumerado. Si esto es un problema, puede solucionarlo almacenando las clases de implementación en lugar de las instancias de implementación, y luego simplemente modifique getVisualization() para crear una nueva instancia de la clase de implementación asociada cuando se llame. Esto colocaría una restricción adicional contra las implementaciones VectorVisualization, que cada una necesita proporcionar un constructor público de 0 parámetros que cree una instancia utilizable de la implementación.

+0

Gracias por su respuesta! Ese es un buen punto con el Thread-Safety. Pero en nuestro caso, no debería ser un problema. Otra forma de proporcionar una funcionalidad similar sería usar un mapa donde usaría la enumeración como clave y VectorVisualization como un valor. Pero cuando agrega una nueva implementación, debe definirla en dos ubicaciones de código en lugar de una con la enumeración ... Así que todavía estoy en el lado de la enumeración :). – Prine

+0

@Prine - Sí, he utilizado el enfoque basado en mapas varias veces en el pasado, pero no proporciona ningún beneficio sobre lo que ha hecho con la enumeración (posible excepción: puede agregar nuevas entradas al mapa dinámicamente en tiempo de ejecución, y/o eliminar los existentes), así que no lo mencioné. La próxima vez que lo necesite, probaré tu idea enum. – aroth

1

Usando una enumeración para enumerar las implementaciones actuales, tiene una serie de propiedades muy agradables. P.ej. es bastante fácil encontrar todas las implementaciones actuales, ya que, por definición, deben enumerarse en la declaración de enumeración y tiene la interfaz estándar enum para acceder a las implementaciones.

Pero también hace que sea imposible ampliar el conjunto actual de una manera conectable, por lo que un tercero no puede agregar una nueva implementación. Por esta misma razón, normalmente me gusta usar un administrador de singleton que contendrá todas las implementaciones. Este patrón también funciona muy bien con muchos marcos de componentes como OSGi.

Cuestiones relacionadas