java - Java 中的 Fluent Builder/DSL 示例

标签 java tree dsl fluent api-design

我有一个 Java 应用程序,我需要在其中将一个简单的算术表达式表示为一棵树。我将支持的操作包括一元(!、一元否定等)、二元(+、-、*、/)甚至三元(自定义函数)操作。因此,我选择了 DefaultMutableTreeNode作为表示我的数学树的结构,因为这些树可以有 0+ 个子节点。

例如,表达式:3 + 4 * someFunc(2, 6, 9)将表示为以下树:

        *
       / \
      /   \
     /     \
    +     someFunc
   / \       /|\
  /   \     / | \
 3     4    2 6  9

这是因为运算符优先级(乘法胜过加法,someFunc 方法必须先解析为一个值,然后它才能作为根乘法的参数)。

无论如何,我需要一种方法来轻松地以编程方式构建这些树,并且想使用 Java DSL(Fluent Builder 模式)来完成此任务。

对于节点:

public abstract class MathNode {

}

public abstract class OperatorNode extends MathNode {

}

public class Addition extends OperatorNode {
    // Same for Multiplication, SomeFunc, and every other supported operator.
}

public class Number extends MathNode {
    // 3, 4, 2, 6, 9, etc.
}

然后,我可能会像这样拥有一个流畅的构建器/DSL:

// Uses DefaultMutableTreeNode for internal structure.
MathTreeBuilder treeBuilder = new MathTreeBuilder();

treeBuilder.multiply()
    .add(3,4)
    .someFunc(2,6,9);

MathTree tree = treeBuilder.build();

然而,我在这里很难透过“树木”看到“森林”。我是否需要构建器,或者我是否可以通过将 DSL 与 MathTree 分开来完成同样的工作?本身? DSL 会是什么样子——我是在走上正轨还是我误解了流式构建器模式的使用?而且,最重要的是,在每种不同的 DSL 方法( add()multiply()someFunc() 等)中,我实际上如何着手修改 DefaultMutableTreeNode准确地表示树?

最佳答案

我认为您应该按照 XML 构建器的工作方式来处理:

  • 是的,使用流畅的 API;
  • 无需严格遵循构建器模式:您不必通过“导出”到不可变对象(immutable对象)来完成构建;
  • 在您的构建器内部,维护树和您在其中的当前位置:当前接收子节点的节点;
  • 有一个明确的 end() 方法,它使当前节点的父节点成为新的当前节点。

然后你可以构建你的 3 + 4 * someFunc(2, 6, 9) 如下:

new MathBuilder()
.add()
  .const(3)
  .multiply()
     .const(4)
     .someFunc()
        .const(2)
        .const(6)
        .const(9)
     .end()
 .get();

所有尾随的 end() 调用都可以省略。我留了一个作为例子。

关于java - Java 中的 Fluent Builder/DSL 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22461333/

相关文章:

java - 此 HQL 查询是否有糖语法

python - 按层次顺序打印树的内容,使用eval函数读取python中的输入树

ruby - 在 REPL 或 irb 中重用 Ruby DSL?

serialization - 支持序列化协程的语言

java - 从网站访问视频内容

java - 异步任务方法 : I get error whether I write "@Override" annotation or not

list - 理解 SICP 中的树 - 练习 2.24

c++ - 随机递归AVL树高误差

elasticsearch - 如何在Kibana DevTools中组合多个查询,以便每个查询都得到一个结果?

java - ImageView 导致延迟