有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

c#为流畅的界面生成器添加分支

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

        PipeFilter pipeFilter = PipeFilter.StartBuild()
            .AddFilter(new SomeFilter1())
            .AddFilter(new SomeFilter2())
            .AddFilter(new SomeFilter3())
            .AddFilter(new SomeFilter4())
            .Build();

显示的代码按预期工作。以下是系统的“图片”:

SomeFilter1 -> SomeFilter2 -> SomeFilter3 -> SomeFilter4

现在,有一种滤波器,它不是一个输出,而是两个输出。我称之为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) 个答案

  1. # 1 楼答案

    我会走下面的路

    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();
    

    在更多格式方面,我将分叉类定义为Filter接口的实现者

    分支可以有任意数量的输出过滤器,使用Output对象链接。为了区分这些输出对象,它们都有一个索引

    因此,AddBranch创建一个新的分叉对象并将其添加,而withOutput(int)是一个静态方法,创建一个Output对象,该对象具有所有必需的方法。请注意,这一点意味着您摆脱了Builder和builded对象之间的经典区别,转而使用在Filter的基本接口中定义Builder方法的代码

  2. # 2 楼答案

    可以按照您的设计实现该系统

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

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

  3. # 3 楼答案

    我认为你受到了符号的限制。在最底层,过滤系统可以由基本过滤器、顺序和并行组合组成。您的第一个示例可以(用伪代码)编写:

    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())));
    

    虽然看起来很麻烦,但我建议用这种方式构建界面(称为“函数式”界面,与“命令式”界面相对应),然后编写方便的方法来减轻一些结构性负担,例如SeqParallel的变量,它们接受任意数量的参数,但最好是将这些变量简单地委托给二进制变量的折叠

    为了详细说明更微妙的设计问题,您使用的类或接口是过滤器生成器,而不是过滤器本身ParallelSeq是该类上的方法。这使您可以选择以多种方式实现组合器,以实现多种解释。我会这样编写界面:

    interface FilterBuilder<Filter> {
        Filter Seq(Filter a, Filter b);
        Filter Parallel(Filter a, Filter b);
    }
    

    它可能不适合您的需求,但它是一种很好的、灵活的设计模式,似乎并不广为人知