【问题标题】:Strategy pattern with different method signatures具有不同方法签名的策略模式
【发布时间】:2017-06-05 22:14:59
【问题描述】:

使用策略模式,如何根据不同的参数来区别对待不同的执行方法?

3 个示例策略

public function execute(string $param1, string $param2)
{
    // Do something specific to this method
    //


    // Do some generic things across all strategies
    //
}

public function execute(string $param1)
{
    // Do something specific to this method
    //


    // Do some generic things across all strategies
    //
}


public function execute()
{
    // Do something specific to this method
    //


    // Do some generic things across all strategies
}

所有人都做一些非常具体但需要不同参数的事情,然后他们做一些通用的事情,每个策略都会做。

【问题讨论】:

  • 你如何弄清楚每个函数需要的参数是什么?参数选择必须是策略的一部分,而不是界面的一部分。
  • 是否可以在构建策略时传入所有需要的数据并从策略界面中删除参数?如果你能做到这一点,那么也许还将算法的通用部分移至抽象的基本策略。或者,让您的策略接口期待一个数据包(1 个模型/对象),并让策略实现有选择地使用其中的一部分。

标签: design-patterns strategy-pattern


【解决方案1】:

使用策略模式,如何处理不同的执行方法 就他们有不同的参数而言不同吗?

如果你让它以这种方式工作,它就不会被视为strategy 模式。您的客户知道不同的策略需要不同的参数这一事实使策略模式无效,因为假设客户知道(至少部分)内部特定策略的作用。

了解策略不应选择性地接受参数。相反,它应该有选择地处理参数。因此,在您进一步阅读之前,请考虑我们现在拥有接受所有参数的所有策略。这样Strategy1 只使用param1param2 而忽略param3,等等。

function execute(param1, param2, param3) { }

但是,如果您有更多参数,这会变得很难看。您可以改为使用单独的 Parameter 类并将此参数集合传递给每个策略。每个策略都将包含一个逻辑来获取和使用它需要的参数并将忽略休息。

然后他们会做一些每个策略都会做的通用操作

这就是您可以使用抽象策略的目的。它将包括abstract execute() 方法和它自己的execute() 方法,每个具体策略都会调用。

总而言之,它的外观如下(不可编译的代码):

Main()
{
    AbstractStrategy s = new ConcreteStrategy1();
    s.Execute(parameters); // parameters -> collection
}

class AbstractStrategy {
    Execute(parameters); // abstract
    Execute() {} // not public
}

class ConcreteStrategy1 : AbstractStrategy {
    override Execute(parameters) {
        string pvalue1 = parameters.GetValue("param1");
        base.Execute();
    }
}

【讨论】:

    【解决方案2】:

    如果您要求将一个操作的输出作为其他操作的输入,并且在此过程中如果参数数量及其类型发生变化,您可以考虑以下设计。

    [伪代码]

    interface IProcess //你可以在这里抽象出具有共同签名的操作, 如果 //需要

    class ProcessOne : IProcess
    {
    private IProcess nextProcess = new ProcessTwo()
    public retVal1 Execute(param1, param2)
    {
    //ProcessOne Logic
    retVal1 retval =  nextProcess.Execute(param1);
    return retval;
    }
    }
    

    然后实现工厂来构造链式 IProcess 类型。 从工厂获取包装的 IProcess 实例并在其上调用 Execute。 在 nextProcess 实例和级联输出上内部调用链式执行操作。

    Factory 使您可以在每个级别使用相同签名的不同实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      相关资源
      最近更新 更多