2012-01-25 129 views
0

我正在编写一个规范,希望陈述(以明确的方式)程序员使用此模式:这种模式的名字是什么?

我们必须对正在处理的数据应用多个过滤器。该配置允许创建这些过滤器。可以有几个,或没有。我不想在导出类中使用这种逻辑(因为它可能会在未来变得很大,使用不同类型的过滤器,我们现在无法预见)。我希望它们一个接一个地运行,所以我将要求在导出类中添加一个方法:“addFilter”,它应该将对象存储在内部数组中,然后在实际导出过程运行时让它们执行。

我不知道问题是否足够清楚。这就像一个链式战略,但不完全是一个策略,因为它根本不是强制性的。

同样,问题是:我应该如何在规范中调用此模式?


编辑:什么我试图做一个例子:

$report = new Report(); 
$report->addFilter(new RemoveSpaces()) 
     ->addFilter(new SubstituteText($predefined_substitutions_array) 
     ->addFilter(new FixCapitals()) 
     ->addFilter(new Encode("utf8")); 
echo($report->generate()); // filters are actually used during generation. 

据称,用户应该能够决定是否RemoveSpaces与否,代替什么文本,是否利用单词与否,使用什么编码等。将来肯定会在用户(客户端,实际)请求中添加一些过滤器。

一旦分解,过滤器应该有一个简单的界面,该报告将称:

foreach($this->filters as $current_filter) { 
    $data = $this->filters[$current_filter]->applyTo($data); 
} 
+0

你可以添加一个伪代码示例来说明你在说什么吗? –

+0

查看编辑的问题。 –

回答

1

我实际上会说你没有包含足够的代码来确定哪个模式可以用来实现你的目标,因为你没有显示你的Filter类的一些示例代码或签名。

Report类如何与Filter类交互(反之亦然)?

我不认为它是一个经典的责任链,因为在这种情况下,每个参与者负责调用下一个参与者,通常使用自己的代码在执行之前或之后执行。想想Windows如何将WindProc链接到您可以在prio WindProc之前或之后执行代码的位置,并且可以选择不调用它。

如果实现与核心对象相同的接口然后它们相互包装,这些过滤器对象可能是装饰器。但是你的代码示例有一个简单列表中的对象。在装饰你会经常看到这样的:

FilterA fA = new FilterA(coreObject); 
FilterB fB = new FilterB(fA); 
FilterC fC = new FilterC(fB); 

当然,这并不一定要通过构造这样做,就像我说的,我们需要看到更多的代码,知道这是一个装饰。

我倾向于认为你是在追求一个“管道和过滤器”模式,其中每个操作的输出是下一个的输入,但即使不知道更多,它也不清楚。我无法分辨每个过滤器是否作用于相同的事物(例如巨大的String),或者每个过滤器都应该与Report对象模型的某个方面相互作用。例如,如果某个报表的对象属性为当前的Encoder,那么Encode("utf8")过滤器可能只是配置/安装Encoder子类来处理磁盘持久性策略的一种方式。同时您的SubstituteText($predefined_substitutions_array)作用于报表拥有的参数集合以交换运行时值。

我会建议描述你想达到什么,而不是如何实现它。

+0

“管道和过滤器”它是! –

1

看起来很像Chain of responsibility。请注意,每个过滤器都可以决定不在链上继续。通常会有一个“链”对象传递给每个后续过滤器。

如果你不需要这些链式语义,它可以简单地看作围绕目标对象的proxies

+0

嗯...不是代理服务器,因为我不是试图访问任何东西,而是将简单的转换和/或过滤器应用到我要导出的数据。正如我对@havexz所说的,为了让程序员保持简单,我不会冒险称之为“责任链”。我想我只会描述这个模式。谢谢! –

2

我认为你不一定必须选择一种模式,因为在大多数现实世界的问题中,一种模式通常不包括整个实现。因此,在您的规范中,您可以指定您的实施受到启发的所有模式。你可以记录你的实现与原始模式有什么不同。

在特定情况下,它类似于Chain of Responsibility

你也可以寻找Decorator图案,这就是还旨在实现类似功能的过滤器。

顺便说一句,类似于你的另一个模式是Command Pattern。所以在你的情况下,Reportgenerate就像的Command,过滤器是列表中的命令。

+0

+1 :) 无论如何,我确定它不是Decorator模式,因为它不会添加方法或更改我的数据对象的接口/功能。责任链也是我的猜测,但我不喜欢它的规范,因为我不想误导程序员认为我要求的是比简单的过滤器/数据转换更复杂的东西。 –

+0

我的意思是说,你试图实现的(即过滤器)也可以使用装饰器来实现。装饰者没有必要添加方法,只需要有相同的接口。例如BufferedInputStream,FileInputStream等('BufferedInputStream bin = new BufferedInputStream(new FileInputStream(filename));') – havexz

+0

你是对的,但装饰者似乎有点过于复杂的ocasion。我只需要一个转换函数的包装对象,并且它是否可以配置是否应用它们。 看到我编辑的问题。 我知道这是我想要的模式,而不是装饰者。我想知道它的名字。 –