我有一个小框架,允许我创建一个管道和过滤系统。 我有想法使用流畅的接口来构建管道和过滤系统:
PipeFilter pipeFilter = PipeFilter.StartBuild()
.AddFilter(new SomeFilter1())
.AddFilter(new SomeFilter2())
.AddFilter(new SomeFilter3())
.AddFilter(new SomeFilter4())
.Build();
显示的代码按预期工作。这是系统的“图片”:
SomeFilter1 -> SomeFilter2 -> SomeFilter3 -> SomeFilter4
现在,有一种Filter,而不是一个输出有两个,而是。我称之为bifurcation
。
以下是具有bifurcation
:
|-> SomeFilter2 -> SomeFilter3
SomeFilter1 --|
|-> SomeFilter4
我想实现这样的事情:
PipeFilter pipeFilter = PipeFilter.StartBuild()
.AddFilter(new SomeFilter1())
.AddBifurcation()
.Output1()
.AddFilter(new SomeFilter2())
.AddFilter(new SomeFilter3())
.Output2()
.AddFilter(new SomeFilter4())
.Build();
但似乎我无法做对。这甚至可能吗?
在第一个示例中,我只需要一个PipeFilterBuilder
(由PipeFilter.StartBuild()
返回)。在第二个例子中,我尝试创建其他类型的构建器,但这似乎无济于事。
忘了提一下,我的想法是,我可以在任何我想要的地方筑巢分叉,也就是说,我可以得到满满树枝的“树”!
任何人都可以对此有任何帮助吗?
答案 0 :(得分:2)
我会采取以下方式
PipeFilter pipeFilter = PipeFilter.StartBuild()
.AddFilter(new SomeFilter1())
.AddBifurcation(
withOutput(1)
.AddFilter(new SomeFilter2())
.AddFilter(new SomeFilter3()), /* this separates first and second output */
withOutput(2)
.AddFilter(new SomeFilter4())
)
.Build();
在更多格式术语中,我将Bifurcation类定义为Filter
接口的实现者。
分叉可以有任意数量的输出过滤器,使用Output
对象链接。为了区分这些输出对象,它们都有一个索引。
因此,addBifurcation创建一个新的Bifurcation对象并添加它,而withOutput(int)
是一个创建Output
对象的静态方法,它具有所有必需的方法。请注意,这一点意味着您摆脱了Builder和构建对象之间的经典区别,转而使用在Filter的基本接口中定义Builder方法的代码。
答案 1 :(得分:1)
我认为你被你的记谱所束缚。在最低级别,您的过滤系统可以由原始过滤器,顺序和并行组合组成。你的第一个例子可以写成(伪代码):
pipeFilter = Seq(new SomeFilter1(),
Seq(new SomeFilter2(),
Seq(new SomeFilter3(), new SomeFilter4())));
使用这样的界面,如何将并行(或任何其他类型的组合器)添加到界面中是完全明显的:
pipeFilter = Seq(new SomeFilter1(),
Parallel(Seq(new SomeFilter2(), new SomeFilter3()),
Seq(new SomeFitler4())));
虽然看起来很麻烦,但我建议以这种方式构建你的界面(称为“功能”,反对“命令式”界面),然后编写便利方法以减少一些结构负担,例如{的变体{1}}和Seq
采用任意数量的参数 - 但最好将这些参数简单地委托给二元变体的折叠。
要详细说明这里的微妙设计问题,您使用的类或接口是过滤器构建器,而不是过滤器本身。 Parallel
和Parallel
是该类的方法。这使您可以选择以多种方式实现组合器以进行多种解释。我会写这样的界面:
Seq
它可能不是完美的满足您的需求,但它是一个很好的,灵活的设计模式,似乎并不广为人知。
答案 2 :(得分:1)
可以按照您的设计实施系统。
除了PipeFilterBuilder
之外,您不需要任何构建器,但是您需要一个能够表示过滤器树的数据结构。然后,您的PipeFilterBuilder
会保留对此结构的引用,并跟踪当前的插入点。
您在PipeFilterBuilder
上执行的任何操作都需要更新插入点并返回构建器本身(this
)。调用AddBifurcation
会将当前插入点添加到堆栈中。相反,Output2
会将插入点设置为从堆栈弹出的值。其他功能应该是相当简单的。