策略模式应该是无状态的吗?

发布于 2024-11-10 18:49:49 字数 51 浏览 4 评论 0原文

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

Must a class that is a "gang of four" strategy be completely stateless (ie no fields) or can it contain immutable state (ie final fields)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小忆控 2024-11-17 18:49:49

策略类封装了一个动作,而不是一个事物。因此,尽管如果确实需要的话可以这样做,但在其中保留状态并没有多大意义。将其视为动词,而不是名词。或者至少作为描述动作的名词。另一方面,您始终可以参数化策略并通过方法调用或类似方式将客户端对象的状态传递给它。

此外,一个类是无状态的还是有状态的并不真正取决于其字段上的 final 关键字。示例:

  • 当用于对象时,final 仅意味着对对象的引用不能更改。您仍然可以更改该对象的内容,例如其字段。在这种情况下,您的类是有状态的,尽管它的字段是最终的。
  • 如果该字段确实是一个常量,那么对于大多数意图和目的,您可以将其视为无状态。例如,您可以声明一个字段private static final,然后确保您永远不会执行任何操作来更改引用对象的状态。

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

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

另一方面,如果参数描述了策略的一个特定执行,则只需将其作为参数传递给方法即可。会的。

附加说明:如果我们想要某种带有延迟、调度的执行动作队列,那么使用带有“副词”状态的动作对象是有充分理由的……也有一个模式 - 命令。

A strategy class encapsulates an action, not a thing. So although you could if you really had to, it wouldn't make a lot of sense to keep state in it. Think of it as a verb, not a noun. Or at least as a noun that describes an action. On the other hand, you could always parametrize the strategy and pass the state of the client object to it by method call or similar.

Also, whether a class is stateless or statefull doesn't really depend on the final keyword on its fields. Examples:

  • When used on objects final only means that the reference to an object may not be changed. You can still change the contents of that object, like its fields. In that case, your class is statefull although its field is final.
  • If the field really is a constant, then for most intents and purposes you can consider it stateless. For example, you can declare a field private static final and then make sure you never do anything to change the state of the referenced object.

EDIT: Let's try to distinguish between parameters of strategy itself and parameters of one particular execution of that strategy. If the strategy class is stateless then there is no point in having more than one instance of that class, which makes the object, not the class, represent the action itself and a method execution represent one particular execution of that strategy.

Now, if we have a parameter of the strategy itself it only makes sense that the parameter has the same value for all executions of that strategy. So, it can be placed in a constant, method call that returns a constant (if we don't wan't static stuff), or even hardcoded. As explained above, that can be implemented in the stateless way.

On the other hand, if the parameter describes one particular execution of the strategy, then just pass it as a parameter to the method. It will do.

Additional note: There is a good reason to use action objects with 'adverbs' packed in its state if we want to, say, have some kind of action queue of execution with delay, scheduling... There's a pattern for that too - Command.

你穿错了嫁妆 2024-11-17 18:49:49

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

No, why should it be stateless? The strategy could be anything, it simply represents some runtime pluggable unit of functionality that allows you to extend the modify the behaviour of the consuming class. There is nothing, as far as I know, that suggests the requirement of statelessness, nor immutability.

明天过后 2024-11-17 18:49:49

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

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

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

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

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

Statelessness refers to the fact that no data is preserved between runs of a strategy; i.e. if you execute the same strategy twice, nothing from the previous run of the strategy would carry over. This is beneficial in that it saves you the trouble of having to "reset" your Strategy implementations when needed.

Note that in the description of the Strategy pattern implementation they make reference to a Context (@ page 317 in my book) that contains the data the strategy needs to execute. All the 'state' required by the implementations should probably go in these context objects.

This means that the strategy implementations themselves are stateless, but the pattern as a whole has state as the required data is passed around in a context.

For example, if you had strategy implementations for mathematical operations, there are at least 2 ways to do it. The first would be to set arg1 and arg2 (and 3, and 4...) on the strategy implementations when you construct them. Then when you execute the implementation would grab its fields and do the operation. The problem is, if you run the same implementation again, you have to reset all its fields (or create a new implementation).

The second way would be to create a context that contains all the arguments. The stategy implementations would grab the values it needs off the context. Then you could reuse each instance of your strategy implementation, just passing a new context each time. No worry about recreating new instances of the implementations, or forgetting to reset the implementation instance. Of course, you still need to manage the contexts correctly.

时光瘦了 2024-11-17 18:49:49

策略模式的目的是直接在方法局部范围内处理策略方法参数。当然,策略类本身可以在需要时保存一些字段,但绝对不能将方法参数分配给这些字段,因为如果多次使用策略对象,可能会引入线程安全问题。

The intent of the strategy pattern is to work on the strategy method arguments directly in the method local scope. The strategy class itself can of course hold some fields whenever required, but the method arguments should in no way be assigned to those fields as it can introduce threadsafety problems if the strategy object is used more than once.

莫相离 2024-11-17 18:49:49

是的,因为这主要是算法选择器。具体算法可以有状态,但不能有选择器。

顺便说一下,在这个策略中我们没有一个类。你指的是哪个具体类?扮演什么角色?

Yes, as this is algorithm chooser mostly. Concrete algorithm can have state, but not the chooser.

By the way in this strategy we don't have one class. Which concrete class do you mean? In what role?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文