colithium
colithium

Reputation: 10327

Proper Large Enum Design

I've recently completed work on a molecular/protein viewer for a computer graphics class. Atoms are obviously a very important part of such a program. Currently, I have a big enum that contains each Element (Hydrogen, Helium, etc). Each Element has associated information such as color, radius, etc. I'm using an extension class so I can write:

float r = Element.Neon.Radius();

I also need to be able to get the corresponding enum from it's symbol. I stuck that method in the extension class which is a bit messy:

Element carbon = ElementExtensions.FromAbbreviation("C");

I want to associate a lot more data with particular Element entries but I'm not sure if this is a good design or not. Currently each set of associated data requires a Dictionary to grab the associated data. Perhaps I could use a Dictionar?

If I went with an Element class I'd need to make sure there's only even one instance of hydrogen, one of helium, etc. I like how System.Drawing.Color is designed but I don't think that's exactly what I need (you'd never have to look up associated data for ForestGreen for example).

What's the best way to support a large but well-defined and finite number of specific instances?

Upvotes: 0

Views: 1034

Answers (3)

Pontus Gagge
Pontus Gagge

Reputation: 17258

Define your elements as classes, but use the Flyweight pattern.

Upvotes: 1

Thomas Levesque
Thomas Levesque

Reputation: 292425

An enum doesn't seem a very adequate approach to this problem; instead you should create an Element class with all the information associated to each element, and static readonly properties for each known element:

public class Element
{
    private readonly string _symbol;
    private readonly int _atomicNumber;
    private readonly Color _color


    // Private constructor, since you don't want people to be able to "invent" random elements...
    private Element(string symbol, int atomicNumber, Color color)
    {
        _symbol = symbol;
        _atomicNumber = atomicNumber;
        _color = color;
    }

    public string Symbol { get { return _symbol; } }
    public int AtomicNumber { get { return _atomicNumber; } }
    public Color color { get { return _color; } }


    // Known elements

    private static readonly Element _hydrogen = new Element("H", 1, Color.White);
    private static readonly Element _carbon = new Element("C", 6, Color.Black);
    private static readonly Element _oxygen = new Element("O", 8, Color.Red);


    public static Element Hydrogen { get { return _hydrogen; } }
    public static Element Carbon { get { return _carbon; } }
    public static Element Oxygen { get { return _oxygen; } }


    ...

}

This way all information about an element can be in one place, rather than scattered in many different places

Upvotes: 2

Carra
Carra

Reputation: 17964

If you have a lot of enums you should reconsider if you should be using inheritance instead.

Instead of Element.Neon why not let Neon inherit from Element?

class Element
 int Radius();
 Color Color();
 string Symbol();

class Neon : Element
 int Radius (return x);
 int Color (return Color.Red);
 int Symbol (return "NE");

If you only need one element, consider using a Singleton.

Upvotes: 2

Related Questions