将分叉添加到流畅的界面构建器

时间:2010-12-30 09:25:43

标签: c# java oop fluent-interface

我有一个小框架,允许我创建一个管道和过滤系统。 我有想法使用流畅的接口来构建管道和过滤系统:

        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()返回)。在第二个例子中,我尝试创建其他类型的构建器,但这似乎无济于事。

忘了提一下,我的想法是,我可以在任何我想要的地方筑巢分叉,也就是说,我可以得到满满树枝的“树”!

任何人都可以对此有任何帮助吗?

3 个答案:

答案 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采用任意数量的参数 - 但最好将这些参数简单地委托给二元变体的折叠。

要详细说明这里的微妙设计问题,您使用的类或接口是过滤器构建器,而不是过滤器本身。 ParallelParallel是该类的方法。这使您可以选择以多种方式实现组合器以进行多种解释。我会写这样的界面:

Seq

它可能不是完美的满足您的需求,但它是一个很好的,灵活的设计模式,似乎并不广为人知。

答案 2 :(得分:1)

可以按照您的设计实施系统。

除了PipeFilterBuilder之外,您不需要任何构建器,但是您需要一个能够表示过滤器树的数据结构。然后,您的PipeFilterBuilder会保留对此结构的引用,并跟踪当前的插入点。

您在PipeFilterBuilder上执行的任何操作都需要更新插入点并返回构建器本身(this)。调用AddBifurcation会将当前插入点添加到堆栈中。相反,Output2会将插入点设置为从堆栈弹出的值。其他功能应该是相当简单的。