Design patterns 具有不同方法签名的策略模式

Design patterns 具有不同方法签名的策略模式,design-patterns,strategy-pattern,Design Patterns,Strategy Pattern,使用策略模式,如何根据不同的参数对不同的执行方法进行不同的处理 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

使用策略模式,如何根据不同的参数对不同的执行方法进行不同的处理

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
}
all做一些非常具体的事情,但需要不同的参数,然后他们做一些每个策略都会做的通用的事情

使用战略模式,如何处理不同的执行方法 它们的参数不同吗

如果你这样做,它就不会被认为是一种
策略
模式。您的客户知道不同的战略需要不同的参数,这一事实使战略模式无效,因为这样客户就被假定知道(至少部分地)特定战略在内部的作用

了解战略不应选择性地接受参数。相反,它应该有选择地处理参数。因此,直到你深入阅读,考虑到我们现在已经接受所有参数的所有策略。因此
Strategy1
仅使用
param1
param2
并忽略
param3
,依此类推

function execute(param1, param2, param3) { }
但是,如果有更多的参数,这会变得很糟糕。您可以使用一个单独的
参数
类,并将此参数集合传递给每个策略。每个策略都将包含一个逻辑来获取和使用它所需的参数,并且将忽略rest

然后他们会做一些每种策略都会做的普通事情

这就是你可以使用抽象策略的原因。它将包括
abstract execute()
方法以及每个具体策略将调用的自己的
execute()
方法

总而言之,下面是它的样子(不可编译代码):


如果您需要将一个操作的输出用作其他操作的输入,在本课程中,如果参数的数量和类型发生变化,则可以考虑以下设计。 [伪代码] 接口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允许您在每个级别使用相同签名的不同实现。

如何确定每个函数需要哪些参数?参数选择必须是策略的一部分,而不是界面的一部分。您是否可以在构建策略时传入所有必需的数据,并从策略界面中删除参数?如果你能做到这一点,那么也许还可以将算法的通用部分转移到一个抽象的基本策略。或者,让您的策略接口期望一个数据包(1个模型/对象),并让策略实现选择性地使用其中的一部分。
class ProcessOne : IProcess
{
private IProcess nextProcess = new ProcessTwo()
public retVal1 Execute(param1, param2)
{
//ProcessOne Logic
retVal1 retval =  nextProcess.Execute(param1);
return retval;
}
}