Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 这种策略模式的变体有名字吗?_Design Patterns - Fatal编程技术网

Design patterns 这种策略模式的变体有名字吗?

Design patterns 这种策略模式的变体有名字吗?,design-patterns,Design Patterns,我有一个标准的GOF策略模式:客户机代码包含对抽象策略的引用,它指向从抽象策略派生或实现抽象策略的几个具体策略中的任意一个 一个ConcreteStrategy根据其传递的参数委托给其他几个ConcreteStrategy中的任何一个,例如: public class ConcreteStrategy0 { public void doStrategy(SomeType someData) { switch( somefunc(someData ) { case 0: Concre

我有一个标准的GOF策略模式:客户机代码包含对抽象策略的引用,它指向从抽象策略派生或实现抽象策略的几个具体策略中的任意一个

一个ConcreteStrategy根据其传递的参数委托给其他几个ConcreteStrategy中的任何一个,例如:

public class ConcreteStrategy0 {
public void doStrategy(SomeType someData) {
   switch( somefunc(someData ) {
    case 0: ConcreteStrategy1.singleton.doStrategy(someData); break; 
    case 1: ConcreteStrategy2.singleton.doStrategy(someData); break;
    default: ConcreteStrategy3.singleton.doStrategy(someData); break;
   }
}
这不是一封完全相同的信封/信件(因为目的不完全相同)


但是它有名字吗?

它看起来像是策略和模式的结合。我怀疑它有自己的名字。 但是为什么你真的需要switch语句呢?我认为安在这里会更好。

它看起来像一个
doStrategy
对具体策略了解得太多,每当添加新的具体策略时,您都必须更新
doStrategy

上面的代码违反了,我想知道它是否可以命名,或者是否有上面的
code
的名称


思考之后: 当调用
ConcreteStrategy0.doStrategy
时,您基本上是像这样调用它

new ConcreteStrategy0().doStrategy(someData);
虽然它本可以更好地重构为

// Inject strategy: Delegate object creation to a factory
new ConcreteStrategy0().doStrategy(StrategyFactory.Create(), someData);

// And update "doStrategy" to,
public void doStrategy(IStrategy strategy, SomeType someData)
{
    strategy.singleton.doStrategy(someData);
}
或者将响应完全委托给策略

// OR Let the strategy do stuff instead
StrategyFactory.Create().doStrategy(someData);

在我看来,它就像一个调度器:它接受一个请求,并根据一些参数决定将其重定向到哪个处理程序

我同意按原样实施违反了开放-封闭原则(添加新策略时会发生什么?)。更好的解决方案是(使用spring配置):


课程安排如下:

class Client {
  Strategy strategy;
  public void setStrategey(Strategy strategy {... }
  public void doSomething(...) {
    ...
    strategy.doStrategy(...);
    ...
  }
}

class DispatcherStrategy implements Strategy {
  Map<Integer,Strategy> strategies;
  Strategy fallbackStrategy;
  ... getters, setters ...
  public void doStrategy(...) {
    Strategy s  = strategies.get(keyFromArguments);
    if ( s==null ) {
      s = fallbackStrategy
    }
    s.doStrategy(...)
  }
}
类客户端{
战略;
公共无效设置策略(策略{…}
公共无效剂量测定法(…){
...
策略、剂量策略(…);
...
}
}
类DispatcherStrategy实现策略{
地图战略;
战略与战略;
…能手,二传手。。。
公共无效剂量策略(…){
Strategys=strategies.get(keyFromArguments);
如果(s==null){
s=后备战略
}
s、 剂量策略(…)
}
}

通过这种方式,策略的任何更改都只会更改应用程序的配置,而不是代码。

切换是为了说明代码的作用,而不是坚持特定的实现。然而,在实践中,我不知道,在具体策略的实现中,我想委托给st的另一个类层次结构策略。哦,它不是工厂,我不认为:工厂是一个对象创建的分页器,这里没有创建任何东西,更不用说创建一个子类类型。我们只是在三个备选方案中进行选择。您的示例中的switch语句非常突出,所以不能简单地忽略它。它是设计的一部分这里的挑战是如何使用其他更优雅的方式来摆脱它()。顺便说一句:即使你返回一个预先创建的单例实例,你仍然可以使用工厂模式。工厂不是真正创建对象的事实对客户端来说并不重要。
class Client {
  Strategy strategy;
  public void setStrategey(Strategy strategy {... }
  public void doSomething(...) {
    ...
    strategy.doStrategy(...);
    ...
  }
}

class DispatcherStrategy implements Strategy {
  Map<Integer,Strategy> strategies;
  Strategy fallbackStrategy;
  ... getters, setters ...
  public void doStrategy(...) {
    Strategy s  = strategies.get(keyFromArguments);
    if ( s==null ) {
      s = fallbackStrategy
    }
    s.doStrategy(...)
  }
}