状态模式与枚举类型

14

有时需要为对象的状态提供支持,根据我的理解有两种方法:

  1. 枚举(简单)
  2. 状态模式(OC原则)

很明显需要使用状态模式来实现这样的目的(我不确定)。

但是在阅读其他代码时,我经常只看到枚举而没有看到状态模式。状态模式是否有效?


“状态模式是否具有强大的能力?”这句话是什么意思? - Brady
大多数函数式语言已经添加了数据类型以满足不同状态下需要具有类型的需求。请参阅F#的区分联合 - Steve
2个回答

15

通常,ENUM方法涉及一些状态和转换的表格(数组)。而设计模式则使用对象来完成相同的任务。

如果您不是指使用ENUM表格方法,则解决方案需要包含一个大型if/else if块,这种方法非常难以管理。根据下面的部分,我认为这种特定解决方案明显是劣质的。

以下是每种方法的优点和缺点:

ENUM表格

优点:

  • 更容易查看所有状态和转换,因为该表在一个地方定义。

缺点:

  • 状态和转换更加硬编码,需要更多的代码更改才能进行扩展。

设计模式

优点:

  • 通过添加新对象更容易扩展新状态。(开闭原则)
  • 更容易确保所有信号都由状态处理,因为基类应该将信号定义为抽象函数。
  • 通过从状态派生来更容易扩展特定状态的行为。状态模式应该将特定状态的行为放入一个对象中。

缺点:

  • 通过查看代码,更难以看到所有状态及其关系,因为它们分散在几个不同的类中。
  • 可能会创建数量庞大的对象。但是,与相应的ENUM解决方案所需的if/else块相比,这种情况更容易管理。

13

为什么我们要使用状态模式?为了消除条件逻辑的重复,并用多态性替换条件代码。

什么时候会出现条件逻辑的重复?当我们有许多动作依赖于状态时,因此您必须在每个动作中重复您的条件逻辑。当您有许多状态时,这变得非常烦人。而且代码重复意味着在添加新状态时,您应该更新所有重复代码的副本。

因此,如果我没有重复的条件逻辑,我宁愿使用基于枚举的状态,而不是创建具有许多状态类的新类层次结构。有时我甚至更喜欢条件逻辑的重复:例如,当我有许多状态但只有少数依赖于状态的动作时。在这种情况下,我更喜欢有两个switch块,而不是创建十个新类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接