Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using enums as a container of implementations

I'm currently working on a project where we have to represent a set of vectors in a 3D environment. We have several different visualization implementations.

I came to the idea, that I could bundle all the visualization types in an enum. I have defined an Interface VectorVisualization and several implementations which implement this interface.

Now I have added to the Interface class the following enum:

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);
}

The label is for a JComboBox in the Gui. So I can now just iterate over the enum and get the label of the different types. Also to set a Implementation I can use the enum like that:

VectorVisualizationType.CYLINDER.getVisualization()

But is this a nice way? Or are there any problems with that approach? Of course, now when you've created a new implementation you have to add this to the enum.

Thanks for your opinion!

like image 270
Prine Avatar asked Nov 04 '22 16:11

Prine


1 Answers

Interesting. I've used enumerated types to carry around useful bits of metadata before, but never taken it quite so far as storing pieces of executable code.

That said, the only issue I see with your approach is that, as you have already noted, when you create a new VectorVisualization implementation you will have to manually add a new entry to the enumeration. Generally I prefer to avoid such manual overhead where possible, but really that's a matter of personal preference.

If you (and everyone else working on this code with you) are aware of this constraint and don't mind it, then I think your solution is fine.

Do note that your current structure requires every VectorVisualization to be implemented in a thread-safe manner, because there is only a single instance that is handed out to everyone who references it through the enumerated type. If this is an issue you could work around it by storing the implementation classes against the enumeration instead of implementation instances, and then simply modify getVisualization() to create a new instance of the associated implementation class when it is called. This would place an additional restriction against VectorVisualization implementations, that each one needs to provide a public 0-parameter constructor which creates a usable instance of the implementation.

like image 153
aroth Avatar answered Nov 10 '22 13:11

aroth