【发布时间】:2019-10-04 21:09:31
【问题描述】:
我首先要说,我已经阅读了很多关于避免使用 instanceof 的问题,但我真的看不出任何与我们所看到的情况完全相符的问题。不过,如果您确实看到任何解决此特定问题的内容,请告诉我!
我们现在面临一个问题,我们有一个类负责保存有关在特定时间要采取的操作的信息。这些时间可以是一个单一的动作或在一段时间内重复出现。我们有一个字段(动作的持续时间)仅对重复动作有效。我们最初有一个用于时间类型的 Enum 和一个用于持续时间的单独字段,作为单个类的一部分。
class Action {
long duration;
Enum timeType;
}
改为:
class Action {
TimeTypeStrategy timeTypeStrategy;
}
class RecurringTimeTypeStrategy extends TimeTypeStrategy {
long duration
}
class SingleTimeTypeStrategy extend TimeTypeStrategy {
}
abstract class TimeTypeStrategy {
}
因此,使用此修改后的代码,我们基本上可以说我们甚至只能有一种类型或另一种类型,并且持续时间只能是循环时间类型的属性。然而,这也意味着,每当我们想要让 action(或其他使用 action 的类)根据其循环时间类型来处理它时,它需要在 timeTypeStrategy 字段上调用 instanceof 来实际检索持续时间并执行它需要的任何调度。
一种想法是,可以将决定成为特定时间类型意味着什么的努力转移到策略本身中。感觉它也应该基于名称,但这需要大量更改一些调度代码,并最终打破了在开发这些调度时开发的一些范式。也许这就是我们需要的解决方案,但感觉不应该是唯一的解决方案。
就设计模式而言,有没有更好的方法,不会导致代码异味,允许调用者根据这些字段决定要做什么?
【问题讨论】:
-
什么代表
duration?为什么只有重复的动作有持续时间?执行一次的动作没有持续时间,它只是立即发生? -
你可以这样想。归根结底,这背后的原因并不重要,因为我可以将接口更改为 IceCream 并将类更改为 BoringIceCream 和 FancyIceCream,其中 FancyIceCream 将 splashColor 作为字段。这将等同于同一件事,但如果你真的想要,你可以忽略特定领域背后的推理;)
-
如果您不希望添加
TimeTypeStrategy的新子类,则可以选择访问者模式。它适用于小型、稳定的类层次结构。 -
如果
TimeTypeStrategy确实是一个 Strategy 对象,它应该在内部使用自己的字段,而不是暴露其实现细节(即封装)。与其要求它的数据,不如告诉它对数据做任何需要做的事情。看起来TimeTypeStrategy只是一个用于保存Action状态的数据结构。在这种情况下,我会公开它的数据(而不是称之为策略)。
标签: oop inheritance design-patterns