Let's say I have defined the following class:
public abstract class Event {
public DateTime Time { get; protected set; }
protected Event(DateTime time) {
Time = time;
}
}
What would you prefer between this:
public class AsleepEvent : Event {
public AsleepEvent(DateTime time) : base(time) { }
}
public class AwakeEvent : Event {
public AwakeEvent(DateTime time) : base(time) { }
}
and this:
public enum StateEventType {
NowAwake,
NowAsleep
}
public class StateEvent : Event {
protected StateEventType stateType;
public StateEvent(DateTime time, StateEventType stateType) : base(time) {
stateType = stateType;
}
}
and why? I am generally more inclined to the first option, but I can't explain why. Is it totally the same or are any advantages in using one instead of the other? Maybe with the first method its easier to add more "states", altough in this case I am 100% sure I will only want two states: now awake, and now asleep (they signal the moments when one awakes and one falls asleep).
I prefer the first. You can attach methods and behaviour to the classes, and move away from the switch/case pattern common with enums towards true polymorphism (and its benefits wrt. maintenance - adding new cases etc.).
Real OOPers don't use if
! Prefer polymorphism to conditionals.
Of course there could be situations where the enum
is the way to go (say, if you have a very, very large amount of states or you know that for the domain, it's very likely that all observers will be interested in all transitions), but in the general case, the first option is less complicated. Using the second approach, every listener must repeat the same piece of code:
if (theStateImInterestedIn == event.stateType){
/* actual code */
}
And every listener needs this, except for the listeners which react in the same way to all transitions! Code duplication! Aaaaargh! As we all know, repeated code causes bugs (hence the DRY principle), and so we can conclude that your gut feeling is correct - the first option (using two different classes) is the better, as every individual listener implementation will have less boiler plate.
Also; add an else
there and you've got interesting times ahead when you add a new state: Some listeners were interested in both types of events, and so assumed that the else
branch meant "the state I didn't check for in the if
". They now break because the else
clause covers >1 state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With