在继承和枚举之间做出选择

时间:2018-12-20 12:17:59

标签: inheritance design-patterns types enums choice

我上土地课:

class Land{
    double latitude;
    double longitude;
}

土地可以是3种类型之一-陡峭,平原和潮湿。它们之间的唯一区别是-当“坦克”访问这些土地时,会因土地类型而产生不同的成本。

现在,我应该创建LandType枚举:

enum LandType{
    STEEPY, PLAIN, WET
}

,并将其用作Land类中的字段吗?

或者,我应该创建三个Land派生类:SteepyLand,PlanLand,WetLand?做出正确选择的决定因素是什么?

1 个答案:

答案 0 :(得分:2)

如果该类只是一个简单的数据结构,则可以使用枚举:各种土地都具有相同的属性,因此使用多态不会增加价值。

但是如果与使用继承来创建更专业的数据类型并启用多态性相比,湿地需要更多的特定属性。 当Land具有需要特定实现或特定于某个LandType的操作时,您应该使用继承。

如果您需要可扩展性,请考虑继承:有些枚举将来不会更改,例如枚举“播放”可以包含“下一个”,“上一个”和“当前”值,它们不会更改,因为没有其他值。在这种情况下,使用枚举表示土地类型非常有效。但是我们可以想象很多不同的“ LandType”,因此更可能发生更改或扩展枚举的情况。为避免对LandType进行此修改,您可以改为实现新的子类型。例如,许多框架和库都针对它们的异常进行此操作:不是通过修改内部类来提供新的标志,而是被迫通过继承自公共基类型(例如)来提供自定义Exception。 Exception

想象一下要排除Land为“ Wet”的任何Land的{​​{1}}对象的迭代,结果将为“ Steepy”和“ Plain”。但是,当在您的LandType枚举中添加新值'Rocky'且不更改所有过滤器时,您将得到'Steepy','Plain'和'Rocky'。这可能会在不希望出现“ Rocky”或应将其从结果中排除“ Wet”的地方排除在外。您不想随时添加新的LandType来更改现有代码。因此,新型LandType的特定实现将有助于避免破坏现有代码。

编辑: “ ...当“坦克”访问这些土地时,会根据土地类型而产生不同的成本”:因为您在询问设计,所以我向您推荐类似访客模式的东西,以避免膨胀的开关状态。