Reputation: 10327
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
Reputation: 17258
Define your elements as classes, but use the Flyweight pattern.
Upvotes: 1
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
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