当我知道我有一组有限的不同选项时,使用枚举或一组类?
假设我定义了以下类:
public abstract class Event {
public DateTime Time { get; protected set; }
protected Event(DateTime time) {
Time = time;
}
}
之间您更喜欢什么?
public class AsleepEvent : Event {
public AsleepEvent(DateTime time) : base(time) { }
}
public class AwakeEvent : Event {
public AwakeEvent(DateTime time) : base(time) { }
}
在 this:和 this:
public enum StateEventType {
NowAwake,
NowAsleep
}
public class StateEvent : Event {
protected StateEventType stateType;
public StateEvent(DateTime time, StateEventType stateType) : base(time) {
stateType = stateType;
}
}
为什么?我一般更倾向于第一种选择,但我无法解释原因。它是否完全相同,或者使用其中一种而不是另一种有什么优势?也许使用第一种方法更容易添加更多“状态”,尽管在这种情况下我百分百确定我只想要两种状态:现在醒着,现在睡着(它们表示一个人醒来和一个人睡着的时刻)。
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).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我更喜欢第一个。您可以将方法和行为附加到类中,并从枚举常见的 switch/case 模式转向真正的多态性(及其维护方面的好处 - 添加新案例等)。
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.).
真正的 OOP 不会使用
if
!与条件语句相比,更喜欢多态性。当然,在某些情况下,枚举是可行的方法(例如,如果您有非常非常多的状态,或者您知道对于域,很可能所有观察者都会对所有转换感兴趣),但在一般情况下,第一个选项不太复杂。使用第二种方法,每个监听器都必须重复相同的代码:
并且每个监听器都需要这个,除了对所有转换以相同方式反应的监听器!代码重复!啊啊啊!众所周知,重复的代码会导致错误(因此有 DRY 原则),因此我们可以得出结论,您的直觉是正确的 - 第一个选项(使用两个不同的类)更好,因为每个单独的侦听器实现都会有更少的样板。
还;在那里添加
else
,当您添加新状态时,您会遇到有趣的时刻:一些侦听器对两种类型的事件都感兴趣,因此假设else
分支意思是“我没有在if
中检查的状态”。它们现在中断了,因为else
子句覆盖了 >1 个状态。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: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 theelse
branch meant "the state I didn't check for in theif
". They now break because theelse
clause covers >1 state.这取决于你在做什么。如果您只管理状态,那么我会说坚持使用枚举(这就是我会做的)。如果您的状态不仅仅是状态,并且它们的实例具有行为,那么就使用类。
It depends on what you're doing. If you are only managing states, then I would say stick with Enums (It's what I would do). If your states are more than just states, if instances of them will have behaviours, then go with classes.
肯定是第一种方式。需求总是在变化。
而且第一种方式更加干净 - 您可以在任何地方使用基类型,因此不会暴露任何派生类型 - 多态性是最好的。
Definetly the first way. Requirments always change.
Also it much, much more cleaner the first way - you can use the base type everywhere and thus not exposing any of the derived ones - polymorphism in it's finest.
第一个的缺点是你无法改变状态。如果一个对象需要从唤醒状态进入睡眠状态,您需要创建一个新对象并复制信息等。很快它就不起作用了。根据名称,我认为这种情况需要状态改变行为。
枚举的第二个选项将起作用,但它会导致基于状态的 if/switch 语句,如其他海报所述。当您重复相同类型的 switch/if 语句时(if 不是问题,重复的 if 才是问题),最好转向多态解决方案。在这种情况下,您可以用接口或抽象类替换枚举,并拥有任意数量的实现。 switch/if 语句中的行为将进入具体实现中的方法中
The disadvantage of the first one is you cannot change the state. If an object needs to go from awake state to asleep state you need to create a new object and copy the info etc. Shortly it won't work. Based on the names I think state changing behavior is needed this scenario.
Second option with enum will work but it will cause if/switch statements based on the state as other posters noted. The moment you repeat same type of switch/if statement (ifs are not the problem, the repeated ifs are the problem) it might be better to move to a polymorphic solution. In this case you would replace the enum with an interface or abstract class and have as many implementations as you want. The behavior that would go into the switch/if statements will go into methods in you concrete implementations