我是否对我的案例使用策略或命令模式?

时间:2012-05-24 15:52:22

标签: c# design-patterns strategy-pattern command-pattern

我正在实施两种算法:

  • AlgorithmA ,适用于矢量值和
  • AlgorithmB ,适用于 Matrix

算法的共同点是:

  • 两者都是提供相同的“求和”算法 输入序列。对于是否考虑,算法略有不同 是否具有特定价值。它们的计算结果也各不相同 按序列的每个值执行。
  • 两种算法都由同一个对象引用(例如,使用算法进行传输或接收的“Antenna”。
  • 在这两种情况下,我希望能够序列化Vector或Matrix结果。此外,我应该能够使用从早期生成计算的(反序列化的)向量/矩阵值来初始化任何算法。

我首先尝试使用策略模式实现上述功能,但很快我意识到由于类型/值的变化,策略模式可能不是最好的。更复杂的是,我的'Antenna'对象可以在任一方向上使用任何算法:

class Antenna
{
    private AlgorithmParams _algorithm;
}

class AlgorithmParams
{
     private IAlgorithm _transmit;
     private IAlgorithm _receive;
}   

我觉得它多次重复“发送”和“接收”的概念(因为实现IAlgorithm的AlgorithmA本身具有派生类型“AlgorithmATransmit”和“{{1} }'即同一算法中的微小变化取决于方向。)

我还想在算法逻辑和序列化数据之间进行更清晰的分离。

我很高兴听到你对此的看法。谢谢!

1 个答案:

答案 0 :(得分:1)

对我而言,策略模式只不过是使用对象组合来允许一组不同的策略可以在类中使用并在运行时互换。在您的情况下,如果希望Antenna类根据输入值在运行时更改其行为(算法),则可以使用策略模式。如果是这种情况,在Antenna类中,您有一个指向AlgorithmInterface的实例变量,该变量由4个类派生:AlgoATransmit,AlgoBTransmit,AlgoAReceive和AlgoBReceive。这4个类中的每一个都将定义真实的算法。然后,您需要一个检查输入值类型的客户端类,并将天线设置为使用适当的算法。

虽然我没有看到如何应用命令模式,但您的问题可能也是模板方法模式的一个很好的例子,您可以将其用作策略的补充。你可以做的是有一个抽象类,我们称之为AbstractAlgorithm,它有一个“模板方法”,通过调用单独的函数来定义算法的公共流程。这些函数将在子类中被覆盖,例如AlgorithmA,AlgorithmB。

天线的方向可以通过在模板方法中使用“钩子”来解决。钩子基本上是在子类中可以覆盖的函数。

这是一个简单的示例代码。天线利用对象组合和策略,具有指向抽象算法的变量,该算法由2个算法导出。这样,算法的轮廓可以在一个地方指定,每个具体步骤在子类中定义。希望它有所帮助,我希望我能理解你的问题。

class Antenna {
    private AbstractAlgorithm algo;
    void SetAlgo(AbstractAlgorithm newAlgo) {
        algo = newAlgo;
    }
}

class AbstractAlgorithm {

    //this is the template method
    void runAlgo() {   
          step1();        //step1 and step2 are two common steps for both algorithms
          step2();
          if (isMatrixValue())
             step3();            //a hook, only AlgoB will override it.
          if (isTransmitting())
             step4();            //a hook, use for transmit
          else if (isReceiving())
             step5();            //a hook, use for receive

    }

    abstract void step1();
    abstract void step2();
    boolean isMatrixValue() {
         return false;         //default value, to not run step3
    }

}

class AlgorithmA {

    void step1() {
         //some implementation
    }
    void step2() {
         //some implementation
    }

    //use the default false value for isMatrixValue(), not to run step3


}


class AlgorithmB {

    void step1() {
         //some implementation
    }
    void step2() {
         //some implementation
    }
    void step3() {
         //some implementation
    }
    boolean isMatrixValue() {
         return true;         //return true and override step3
    }

}