假设
前几天我听到一位朋友说:
你知道,DSL和builder pattern - 它们基本上是一回事。
对我来说这听起来很奇怪,因为我一直认为DSL总是比Builder模式更具表现力。
我的问题是:构建器模式和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");
答案 0 :(得分:4)
我认为你甚至不能比较这两个不同的概念。
DSL是特定域的语言,但它具有原语和组合规则,允许您谈论特定域。
构建器模式是一种模式,即解决方案模板,您将应用于问题以提出解决方案,然后您使用该解决方案。在您的代码示例中,UserBuilder类不应用构建器模式,它本身不是构建器模式。
您似乎正试图在语法上比较它们,因为您的示例代码正在尝试显示。在两个示例代码中,您在语法上显示DSL和构建器模式类都具有相同的功能,即方法调用链,这导致您可以比较它们。我不认为比较是公平的,因为只能让你用同一种语言比较它们,即无法在不同的编程语言中进行语法比较。
您可以使用构建器模式实现DSL,也可以使用其他模式实现DSL。模式是一组问题的解决方案模板,构建器模式是实现DSL问题的一个这样的模板,但它不是唯一的模板。
答案 1 :(得分:0)
当然,DSL包含许多不是构建器模式的东西。所以不,他们不是一回事。
如果你认为每个构建器模式都是DSL(对于构造特定类的对象的域),那么你显然会得到一般的DSL比构建器模式更具表现力。但 a DSL并不比构建器模式更具表现力;任何单个DSL都无法完成构建器模式可以执行的所有操作。
答案 2 :(得分:0)
如果你的朋友说了
你知道,用于构建Plain Old Java Objects ,构建器模式是一种DSL。
......然后我同意了。
但是,在Clojure中,您不需要构建器类或DSL来简洁地构造对象。
鉴于
(defrecord User [first-name last-name age phone address])
......然后
(map->User {:first-name "John"
:last-name "Doe"
:address "Fake address 1234"})
...生产
{:first-name "John",
:last-name "Doe",
:age nil,
:phone nil,
:address "Fake address 1234"}
...这是一张User
记录,虽然它打印得像地图一样。
因此,为此目的,Clojure将 DS 从 DSL 中取出,您只需要使用语言结构。