Two member enumeration vs. boolean value
This question has in the back of my mind for some time, sorry if it appears subjective. There are some disadvantages in using bool in public properties and constructors for data objects. Consider the following code as an example.
Using bool:
public class Room
{
public string Name { get; set; }
public bool Bookable { get; set; }
public Room(string name, bool bookable);
}
and the use of this class
Room r = new Room ("101", true);
This is suitably functional, there is however another way to implement it:
Using enum:
public enum BookingStatus
{
Bookable,
NotBookable
}
public class Room
{
public string Name { get; set; }
public BookingStatus Bookable { get; set; }
public Room(string name, BookingStatus bookable);
}
and the use of this class
Room r = new Room ("101", Boo开发者_JAVA百科kingStatus.Bookable);
To me the two appear functionally equivalent, there are some advantages and disadvantages of each however:
- When setting properties the Enum method is more verbose (you can infer the usage of the enum from the code alone)
- Enumerations can be extended to support further states (particularly useful for an API)
- Enumerations require considerably more typing (although reduces this vastly)
- Enumerations can not be used in conditionals (i.e. if (r.bookable)), although I appreciate this is trivial to resolve.
Am I missing something, totally off the mark? I am not sure why this bugs me so much, perhaps I am too OCD for my own good!
Simply because of readability and understanding of the code, I'll go for enum instead of boolean.
Compare BookingStatus.Bookable
and true
, of course you would understand more reading BookingStatus.Bookable
.
Also like what fforw mentioned, in case in future you might need to add more options, enum would be easier to change.
Ih there is any chance that in the future there might be more than the initial two options, adding a third option to an enum is a lot less work then changing all bool to enum.
For a property I would probably agree. In 'Clean Code' though, it is indicated (correctly) that bool
s hide intent when used as parameters. For example, a formatting method might look like:
public void Format(
bool bold,
bool italic,
bool underline
) {
...
}
When called this looks like:
Format(true, false, true);
Instead it would be much more readable as:
public enum Bold { Yes, No }
public enum Italic { Yes, No }
public enum Underline { Yes, No }
public void Format(
Bold bold,
Italic italic,
Underline underline
) {
...
}
Which then makes the call look like:
Format(Bold.Yes, Italic.No, Underline.Yes);
(Remember this is just an example of how bool parameters hide intent; there are probably better ways to implement the above code.)
In your particular case, notice the difference between the two constructor calls:
// enum; intent is clear
Room r = new Room ("101", BookingStatus.Bookable);
// bool; true what?
Room r = new Room("101", true);
This can also be improved by using argument names:
Room r = new Room("101", bookable: true);
In his book Refactoring, Martin Fowler explains why he thinks enums are a code smell, and I can only agree. In your example, a better approach would be to make an abstract Room class:
public abstract class Room
{
public string Name { get; set; }
public abstract bool Bookable { get; }
}
Then you can make derived BookableRoom and NonBookableRoom classes.
public class BookableRoom : Room
{
public override bool Bookable
{
get { return true; }
}
}
public class NonBookableRoom : Room
{
public override bool Bookable
{
get { return false; }
}
}
精彩评论