Coding Tip #42: turning enums into classes
In Coding Tip #27 I explained how I rarely like to use booleans to represent states, and prefer to use an enum. Now that I have all nice little enums everywhere, another pattern that I see emerge is that I want more from my enum than just a value: perhaps other values associated with it, or actual behaviour. These enums then get converted into fully-fledged objects (ie classes) in the system with a very simple refactor.
So, the code started with:
private bool hasVehicle;
then, by following Coding Tip #27, went to:
private Vehicle theVehicle;
public enum Vehicle
{
Car,
MotorBike,
PeopleMover
}
and now can turn into:
private Vehicle theVehicle;
public class Vehicle
{
public static Vehicle Car = new Vehicle("Car");
public static Vehicle MotorBike = new Vehicle("MotorBike");
public static Vehicle PeopleMover = new Vehicle("PeopleMover");
private Vehicle(string name)
{
this.name = name
}
private string name;
}
so my objects are all setup to add additional functionality:
private Vehicle theVehicle;
...
theVehicle.WillSeatAPartyOf(4);
...
public class Vehicle
{
public static Vehicle Car = new Vehicle("Car", 5);
public static Vehicle MotorBike = new Vehicle("MotorBike", 2);
public static Vehicle PeopleMover = new Vehicle("PeopleMover", 8);
private Vehicle(string name, int passengerLimit)
{
this.name = name
this.passengerLimit = passengerLimit;
}
private string name;
private int passengerLimit;
public bool WillSeatAPartyOf(int numberOfPassengers)
{
return numberOfPassengers =< passengerLimit;
}
}
I debate whether the class should contain the name or the index, usually I use the name; you can use both. Obviously if someone was now relying on the enum order, you would need to give it the index. Another advantage of this is because the constructor is private, you know that there are a definitive list of representations for it.
I don’t usually use class straight away. Indeed, I usually take bets to see how long it will stay an enum – sometimes the refactor is immediate, other times it remains an enum.
Posted: June 29th, 2009 under Design.
Comments
Comment from Peter Gillard-Moss
Time June 29, 2009 at 4:26 pm
I forgo enums and go straight to classes (except in Java where enums can have behaviour). .NET enums are a waste of time and are syntatic sugar around ints etc. and prone to nastyness (e.g. (int)Vehicle.Car is legit no matter what the value).
Though word of warning: make sure that the class is immutable. I’ve seen people use this technique and introduce bugs because they start doing stuff like:
mycar = Vehicle.Car
car.Doors = 6
Pingback from Round Up No.3 « DevRoundUp.net
Time June 30, 2009 at 9:47 pm
[...] Coding Tip #42: turning enums into classes: Sarah Taraporewalla finds that her Enums keep turning into classes . [...]
Comment from Dan
Time July 28, 2009 at 4:23 pm
Is this not just a reworked polymorphic approach?
Comment from Sarah
Time August 3, 2009 at 7:37 am
Yep – but it’s still amazing how many times I need to call it out to people
Comment from Ola Bini
Time June 29, 2009 at 9:02 am
It strikes me that in most cases where this pattern is relevant, it is exactly in the kind of cases you show above – and the reason you have to refactor in C# is because the enums aren’t real objects.
In Java, this pattern doesn’t exist, because Enum’s are objects, and when you define them you can define different behavior for the different values and so on, or just different arguments to creation.
Have you seen any case where what you want to do goes outside of that?