修改后的策略设计模式


11

我最近开始研究设计模式,除了一点点不同之外,我正在编写的一件事将完全适合于战略模式。

本质上,我的某些(但不是全部)算法需要一个或两个额外的参数传递给它们。

所以我要么需要

  • 当我调用他们的calculate方法时,给他们传递一个额外的参数

要么

  • 将它们存储为ConcreteAlgorithm类中的变量,并能够在调用算法之前对其进行更新。

有满足这种需求的设计模式吗?在坚持策略模式的同时如何实现?

我考虑过将客户端对象传递给所有算法,并将变量存储在其中,然后仅在特定算法需要时才使用该对象。但是,我认为这既笨拙,又打败了战略模式的意义。

为了清楚起见,我正在用Java实现,因此没有太多的可选参数(可以很好地解决此问题)。


像C ++中那样的可选参数不会解决任何问题,因为它们只是定义多个重载方法的简写。
maaartinus 2011年

我会尽量避免将其他参数存储在必须在使用前更改它们的位置。这样,您就可以使ConcreteAlgorithm成为有状态的,因此无法轻松地将其传递给其他方法或线程。而且,忘记设置参数太容易了。
maaartinus 2011年

Answers:


5

塞缪尔(Samuel),是否可以将每种策略所包含的参数封装到一个公共类中,然后扩展该公共Parameter类以添加某些策略特别需要的更多行为?

例如

StrategyParameter //Base strategy parameter that most of the strategies need
        ^
        |
        |
SpecialStrategyParameter // will be used for strategies that need more parameter

然后,定义策略层次结构,如下所示:

Interface MyStrategy {
   void myStrategyMethod(StrategyParameter parameter);
}

class MyNormalStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}

将上述策略称为: myNormalStrategyInstance.myStrategyMethod(strategyParameter);

class MySpecializedStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}

通过传递SpecialStrategyParameter实例来调用上述策略,例如:mySpecializedStrategy.myStrategyMethod(specialStrategyParameter);

如果不清楚,请更新。乐于解释/澄清。


2
-1需要下调,中断设计的封装。尽管这是对设计的改进,但还有更好的方法可以使这只猫蒙皮。
tallseth

@tallseth我也看到沮丧。但我看不出更好的方法。您能否指出一个更好的解决方案?文章还是什么?
Narek

其实,是。根据问题中的详细信息,@Jordão会提供我希望的答案。这个答案发挥了战略模式的优势。如果我们在此答案中采用该方法,则我希望StrategyParameter包含所有可能的参数,就像DTO一样。该策略的某些实现可能会忽略它们。在某些情况下,这是最好的方法。对于此类问题,上下文为准。
塔斯2015年

4

您需要阐明您的策略

这完全取决于您如何使用算法。为了使您的客户类可以互换使用不同的策略实现,它们都需要具有通用的抽象。如果它们不遵循相同的界面,则可能您需要的是不同的抽象

我之前使用过可配置策略,在此您可以对构造中的具体类进行参数化:

interface Strategy {
  int calculate();
}

class ConcreteStrategyThatNeedsAParameter implements Strategy {
  private final int param;
  public ConcreteStrategyThatNeedsAParameter(int param) {
    this.param = param;
  }
  public int calculate() { 
    // uses param...
  }
}

现在,仍然有人需要创建此类的实例并将其传递给您的客户端。但是您的客户仍然只需要了解该Strategy接口。

如果您的策略方法接受参数,它也可以工作,但是您的客户知道这些参数,并将它们传递给它使用的所有实现。


客户端是具有上下文的提供参数的客户端。
andyczerwonka '16

1

只要在接口上清楚地定义了签名,它仍然符合策略模式。

所写的模式是绝对最简单的形式,仍然可以表现出预期的行为,因此只要保持原始意图,就可以修饰它们。那当然是假设您要遵循这种模式。如果模式不适合,或者仅仅因为它在那里就没有意义,但是就您而言,我认为您还可以。


0

扩展Peakit提供的上述答案-您可以使用抽象。我在这里使用Peakit的代码-

接口MyStrategy { abstract void myStrategyMethod(StrategyParameter parameter); }

类MyNormalStrategy扩展MyStrategy {公共重写void myStrategyMethod(StrategyParameter parameter){//在此处实现逻辑}}

类MySpecializedStrategy扩展了MyStrategy {公共重写void myStrategyMethod(StrategyParameter parameter,ExtraStrategyParameter extraParameter){//在此处实现逻辑} }

如果我正确理解了您的问题,您想将一个额外的参数传递给某些算法,对吗?请让我知道这是您要找的东西吗?


0

如果看一下《设计模式》一书,那本身并没有错,存在一些使用较少或不使用任何传递参数的SimpleStrategy,或者这些参数是一个“一字通” /“最小通配”的乘数。这里的设计选择是,这是否会在最终没有使用的额外处理方面对您造成伤害。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.