看完视频《Clean Code Talks -- 继承、多态和测试》后,我检查了我的代码,发现有几个switch语句可以重构成多态,但我也注意到我只在枚举类型上使用了switch语句。这是否意味着枚举在面向对象设计中是“邪恶”的,应该用多态来消除它们?
看完视频《Clean Code Talks -- 继承、多态和测试》后,我检查了我的代码,发现有几个switch语句可以重构成多态,但我也注意到我只在枚举类型上使用了switch语句。这是否意味着枚举在面向对象设计中是“邪恶”的,应该用多态来消除它们?
枚举本身并不是邪恶的,邪恶的是switch语句。在C++ FAQ Book中有一个长时间的讨论,但要点是:除了有限的领域 --- 例如从设备寄存器中读取数据的解释 --- 一个大的switch语句意味着您正在使用数据来区分子类型。相反,您应该只使用子类型,以便获得编译器的帮助来保持其正确性,并且这也意味着编译器将在您(不可避免地)更改情况集时自动添加新的情况。
class Sunday extends DayOfWeek {}
class Monday extends DayOfWeek {}
class Tuesday extends DayOfWeek {}
class Wednesday extends DayOfWeek {}
class Thursday extends DayOfWeek {}
class Friday extends DayOfWeek {}
class Saturday extends DayOfWeek {}
枚举类型很好。
var day = DayOfWeek.Tuesday; var localized = CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int)day];
- recursive我不太愿意称任何东西为“邪恶”。这是一个问题,涉及到“你想要多么重的工程”。
枚举/开关在某些领域是可以的。设置类层次结构是不总是需要的开销。但是,如果 case 语句中的代码越多,那么你可能需要采用更加复杂的方法。
我的经典经验是几年前我为班级编写的编译器。我的室友和我上了同样的课,但我们采用了两种非常不同的方法。我采取了一种重度面向对象的方法,充满了多态性。他采用了一种重度 C 语言方法,使用枚举和联合。他的代码行数大约是我的一半,编译速度更快,而且他的代码能够正常工作。他的代码很灵活,因为它没有被过度设计。这对我来说是软件设计方面的宝贵经验。
这是否意味着在面向对象设计中,枚举类型是“有害”的,应该用多态性来替代?
通常情况下是这样的。
switch/enum结构可以是许多多态结构之一:状态(State)和策略(Strategy)是最常见的两种。
我认为枚举在数值已知且数量不多的情况下非常有用。
此外,枚举以一种命名常量的方式命名。
枚举没有存储除其值之外的任何其他状态。
当您有不同条件状态(并且条件需要比单个变量依赖更多状态)时,多态将非常有帮助。