Предположения
Я слышал, как друг сказал на днях:
Вы знаете, DSL и шаблон строителя - они в основном то же самое.
Для меня это звучало странно, поскольку я всегда считал, что DSL всегда будет более выразительным, чем шаблон Builder.
Мой вопрос: Является ли шаблон построителя и эквивалент 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");
Я не думаю, что вы можете сравнить эти две разные концепции.
DSL - это язык для определенного домена, то есть он содержит примитивы и правила композиции, которые позволяют говорить о конкретном домене.
Шаблон-строитель - это шаблон, то есть шаблон решения, который вы применяете к проблеме, чтобы придумать решение, а затем вы используете это решение. В вашем примере кода класс UserBuilder выходит из применения шаблона построителя, он сам по себе не является шаблоном построителя.
Кажется, что вы пытаетесь сравнить их синтаксически, как показывает пример кода. В обоих примерах кода вы показываете, что синтаксически, как DSL, так и класс patter-компоновщика, имеют одну и ту же функцию, т.е. цепочку вызовов методов, и это приводит к мысли, что вы можете их сравнить. Я не думаю, что сравнение справедливо, поскольку это может позволить вам сравнивать их на одном языке, т.е. Нет возможности синтаксически сравнивать их на разных языках программирования.
Вы можете реализовать DSL с использованием шаблона построителя или вы также можете реализовать DSL, используя другие шаблоны. Шаблон - это шаблон решения для набора проблем, шаблон-строитель - один из таких шаблонов для проблемы внедрения DSL, но он не единственный.
Если бы ваш друг сказал
Вы знаете, для построения простых старых объектов Java шаблон-строитель является своего рода 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, и вы просто ушли с языковой конструкцией.
Конечно, в DSL есть много вещей, которые не являются образцом строителя. Нет, это не одно и то же.
Если вы считаете, что каждый шаблон построителя является DSL (для области построения объектов определенного класса), то вы, очевидно, получаете, что DSL в целом более выразительны, чем шаблоны построителя. Но DSL не более выразителен, чем шаблон строителя; любая отдельная DSL не может делать все, что может сделать шаблон строителя.