Шаблон компоновки и DSL-эквивалент - или еще один выразительный?

1

Предположения

  • Я ограничу это внутренними DSL, но если вы можете дать мне вескую причину, почему я должен рассматривать внешние DSL - я буду слушать это.
  • Если вы хотите ответить на это в Clojure или Scala и объяснить, почему я ошибаюсь - мне тоже здорово.

Я слышал, как друг сказал на днях:

Вы знаете, 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
clojure
builder

3 ответа

4
Лучший ответ

Я не думаю, что вы можете сравнить эти две разные концепции.

DSL - это язык для определенного домена, то есть он содержит примитивы и правила композиции, которые позволяют говорить о конкретном домене.

Шаблон-строитель - это шаблон, то есть шаблон решения, который вы применяете к проблеме, чтобы придумать решение, а затем вы используете это решение. В вашем примере кода класс UserBuilder выходит из применения шаблона построителя, он сам по себе не является шаблоном построителя.

Кажется, что вы пытаетесь сравнить их синтаксически, как показывает пример кода. В обоих примерах кода вы показываете, что синтаксически, как DSL, так и класс patter-компоновщика, имеют одну и ту же функцию, т.е. цепочку вызовов методов, и это приводит к мысли, что вы можете их сравнить. Я не думаю, что сравнение справедливо, поскольку это может позволить вам сравнивать их на одном языке, т.е. Нет возможности синтаксически сравнивать их на разных языках программирования.

Вы можете реализовать DSL с использованием шаблона построителя или вы также можете реализовать DSL, используя другие шаблоны. Шаблон - это шаблон решения для набора проблем, шаблон-строитель - один из таких шаблонов для проблемы внедрения DSL, но он не единственный.

  • 0
    Спасибо @Ankur - это действительно полезно. (Это то, о чем я тоже думал). Могу ли я попросить пример, где DSL является более выразительным?
  • 0
    @hawkeye: понятие выразительности очень сложно выразить;). Допустим, вы создаете финансовое приложение, и вы также хотите, чтобы пользователь приложения создал пользовательские правила, которые позволяют настраивать приложение. В этом случае создание DSL для пользователей, чтобы выразить свои правила, приведет к большей выразительности, чем просьба пользователя написать правила на родном языке приложения, то есть на языке, на котором было написано приложение.
Показать ещё 2 комментария
0

Если бы ваш друг сказал

Вы знаете, для построения простых старых объектов Java шаблон-строитель является своего рода DSL.

... тогда я бы согласился.

Тем не менее, в Clojure вам не нужен класс строителя или DSL для краткого построения объекта.

  • POJO переводят на записи, которые имитируют (хэш) карты. Существует несколько неуклюжий синтаксис для создания записи с карты.

Данный

(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, и вы просто ушли с языковой конструкцией.

0

Конечно, в DSL есть много вещей, которые не являются образцом строителя. Нет, это не одно и то же.

Если вы считаете, что каждый шаблон построителя является DSL (для области построения объектов определенного класса), то вы, очевидно, получаете, что DSL в целом более выразительны, чем шаблоны построителя. Но DSL не более выразителен, чем шаблон строителя; любая отдельная DSL не может делать все, что может сделать шаблон строителя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню