Предположения
- Я ограничусь этим внутренними DSL, но если вы можете дать мне вескую причину, почему я должен рассмотреть внешние DSL - я выслушаю это.
- Если вы хотите ответить на это в Clojure или Scala и объяснить, почему я не прав — я тоже не против.
Я слышал, как друг сказал на днях:
Вы знаете, DSL и шаблон компоновщика — по сути это одно и то же.
Мне это показалось странным, поскольку я всегда предполагал, что DSL всегда будет более выразительным, чем шаблон строителя.
Мой вопрос: Являются ли шаблон построителя и DSL эквивалентными или более выразительными?
Итак, я посмотрел — вот шаблон User Builder в 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();
}
Вот использование внутреннего DSL в 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");