java - 构建器模式和 DSL 是等效的——还是更具表现力?

标签 java scala clojure dsl builder

假设

  • 我会将其限制为 internal DSLs - 但如果您能给我一个充分的理由,说明我为什么要考虑 external DSLs - 我会听取的。
  • 如果您想在 Clojure 或 Scala 中回答这个问题并解释我为什么错了 - 我也很乐意。

前几天听 friend 说:

You know, a DSL and the builder pattern - they're basically the same thing.

对我来说这听起来很奇怪,因为我一直认为 DSL 总是比构建器模式更具表现力。

我的问题是:构建器模式和 DSL 是等价的——还是更具表现力?

所以我看了一下 - 这是一个 User Builder Pattern in Java :

public class User {
    private final String firstName; // required
    private final String lastName; // required
    private final int age; // optional
    private final String phone; // optional
    private final String address; // optional

    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    public String getPhone() {
        return phone;
    }

    public String getAddress() {
        return address;
    }

    public static class UserBuilder {
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;

        public UserBuilder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }

        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }

        public UserBuilder address(String address) {
            this.address = address;
            return this;
        }

        public User build() {
            return new User(this);
        }

    }
}

下面是上面使用的构建器模式:

public User getUser() {
    return new
        User.UserBuilder("John", "Doe")
        .age(30)
        .phone("1234567")
        .address("Fake address 1234")
        .build();
}

这是 usage of an Internal DSL in Java :

 Person person = constructor().withParameterTypes(String.class)
                              .in(Person.class)
                              .newInstance("Yoda");

 method("setName").withParameterTypes(String.class)
                  .in(person)
                  .invoke("Luke");

 field("name").ofType(String.class)
              .in(person)
              .set("Anakin"); 

最佳答案

我认为您甚至无法比较这两个不同的概念。

DSL 是针对特定领域的语言,即它具有允许您讨论特定领域的原语和组合规则。

构建器模式是一种模式,即解决方案模板,您应用于问题以提出解决方案,然后使用该解决方案。在您的代码示例中,UserBuilder 类来自应用构建器模式,它本身不是构建器模式。

您似乎正试图在语法上比较它们,正如您的示例代码试图显示的那样。在这两个示例代码中,您在语法上都表明,DSL 和构建器模式类都具有相同的功能,即方法调用链,这导致您认为可以比较它们。我不认为这种比较是公平的,因为这只能让你用同一种语言来比较它们,也就是说,没有办法在不同的编程语言之间进行句法比较。

您可以使用构建器模式实现 DSL,或者也可以使用其他模式实现 DSL。模式是一组问题的解决方案模板,构建器模式是实现 DSL 问题的模板之一,但它不是唯一的。

关于java - 构建器模式和 DSL 是等效的——还是更具表现力?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25346672/

相关文章:

clojure - Ring/Compojure 中的 session

java - 我们应该在哪里定义属性

java.lang.NoSuchFieldError : DEF_CONTENT_CHARSET 错误

java - 如何使用 OSM 创建和采样路线

scala - 内部库新版本时是否有可能收到警告?

clojure - 在 LightTable 中,如何更改 Clojure 版本?

Java:递归中可变对象的引用传递

java - 错误 java.lang.StackOverflowError : stack size 8MB

scala - 如何将scala编译成可运行的jar文件

testing - 运行 Midje 测试时出现 FileNotFound 异常