战略模式应该是无国籍的吗?

mur*_*ngu 9 design-patterns strategy-pattern stateless

必须是一个"四人帮"策略的类是完全无状态的(即没有字段)还是它可以包含不可变状态(即最终字段)?

Gor*_*vic 17

策略类封装了一个动作,而不是一个东西.因此,尽管如果你真的不得不这样做,但保持状态并不是很有意义.把它想象成动词,而不是名词.或者至少作为描述动作的名词.另一方面,您可以始终参数化策略,并通过方法调用或类似方法将客户端对象的状态传递给它.

此外,类是无状态还是有状态并不真正依赖final于其字段上的关键字.例子:

  • 在对象上使用时,final仅表示不能更改对对象的引用.您仍然可以更改该对象的内容,例如其字段.在这种情况下,你的班级是有状态的,尽管它的领域是最终的.
  • 如果该字段确实是一个常数,那么对于大多数意图和目的,您可以认为它是无状态的.例如,您可以声明一个字段private static final,然后确保您从不做任何事情来更改引用对象的状态.

编辑:让我们尝试区分策略本身的参数和该策略的一个特定执行的参数.如果策略类是无状态的,那么拥有该类的多个实例是没有意义的,这使得对象(而不是类)表示操作本身,而方法执行表示该策略的一个特定执行.

现在,如果我们有一个策略本身的参数,那么只有该参数对该策略的所有执行具有相同的值才有意义.因此,它可以放在一个常量的方法调用中,该方法调用返回一个常量(如果我们不是静态的东西),甚至是硬编码的.如上所述,这可以以无状态的方式实现.

另一方面,如果参数描述了策略的一个特定执行,那么只需将其作为参数传递给方法.它会的.

附加说明:有一个很好的理由使用在其状态下打包的"副词"的动作对象,比如说,我们想要某种具有延迟,调度的执行动作队列......这也是一种模式 - 命令.


Mal*_*ker 5

不,为什么要无状态?该策略可以是任何东西,它只是代表一些运行时可插拔功能单元,允许您扩展对使用类的修改行为。据我所知,没有任何东西表明无国籍或不变性的要求。


hvg*_*des 5

无状态是指在策略运行之间不保留任何数据;即,如果您执行相同的策略两次,则上次运行该策略的任何内容都不会保留。这是有益的,因为它省去了您在需要时必须“重置”策略实施的麻烦。

请注意,在策略模式实现的描述中,它们引用了包含策略需要执行的数据的上下文(@我书中的第 317 页)。实现所需的所有“状态”可能都应该放在这些上下文对象中。

这意味着策略实现本身是无状态的,但当所需数据在上下文中传递时,整个模式具有状态。

例如,如果您有数学运算的策略实现,那么至少有两种方法可以实现。第一个是在构建策略实现时设置 arg1 和 arg2(以及 3 和 4...)。然后,当您执行实现时,将获取其字段并执行操作。问题是,如果再次运行相同的实现,则必须重置其所有字段(或创建新的实现)。

第二种方法是创建一个包含所有参数的上下文。策略实现将从上下文中获取所需的值。然后,您可以重用策略实现的每个实例,只需每次传递一个新的上下文。不用担心重新创建实现的新实例,或忘记重置实现实例。当然,您仍然需要正确管理上下文。