对无状态策略的困惑

Sus*_*ain 3 design-patterns

在策略设计模式中,提到了无状态策略。任何人都可以通过回答以下问题来帮助我理解它:

  1. 什么是无状态策略?
  2. 它可以解决什么问题?
  3. 在哪里使用和不使用?
  4. 相同的缺点

如果能通过举例说明所有这些,我将不胜感激。

sdg*_*sdh 5

什么是无状态策略?

无状态策略是该策略的每个“运行”都不影响其他“运行”的策略。

以下是两种选择true或的策略false

public final class FlipStrategy {

    private boolean lastPick;

    public boolean pick() {

        lastPick = !lastPick;

        return lastPick;
    }
}
Run Code Online (Sandbox Code Playgroud)

和...

public final class RandomStrategy {

    public boolean pick() {

        return (new Random()).nextBoolean();
    }
}
Run Code Online (Sandbox Code Playgroud)

FlipStrategy是一项有状态策略。您得到的结果取决于先前的结果。

RandomStrategy是一种无状态策略。您获得的结果彼此独立。

它可以解决什么问题?

无状态策略...

  • 可以安全地共享,而无需一个用户更改另一个用户的结果
  • (通常)是线程安全的,从而允许它们在线程之间共享
  • 具有较少的内存开销,因为一个实例可以多次重用
  • 可以临时创建,这可以使程序架构更简单

在哪里使用和不使用此?

并非总是可以使用无状态策略。想像一下保镖的策略-它必须记住已经有多少人进入,以决定是否应允许更多人进入。

否则,无状态策略会更好。

有时,您可以使用“上下文”对象将有状态策略转变为无状态策略。上下文对象将与策略相关的所有状态编码为参数。

在我们之前的示例中,上下文可能是:

public final class Context { 

    public final boolean lastPick;

    public Context(final boolean lastPick) {

        this.lastPick = lastPick;
    }

    // hashCode etc... 
}
Run Code Online (Sandbox Code Playgroud)

现在FlipStrategy可以以无状态方式实现:

public final class FlipStrategy {

    public boolean pick(final Context context) {

        return !context.lastPick;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用上下文对象可以说是一种更简洁的设计。最后选择是世界的财产,而不是战略,因此它不应成为世界的成员。