Java 1.4 расширяемый шаблон построения

#java #design-patterns #generics #java1.4

#java #шаблоны проектирования #обобщения #java1.4

Вопрос:

Я наткнулся на кирпичную стену, когда дело доходит до реализации расширяемого класса, который использует шаблон builder в java 1.4. Сам шаблон работает неплохо, но я наткнулся на кирпичную стену, когда дело доходит до его расширения из-за отсутствия дженериков.

На данный момент лучшее решение, которое я смог придумать, — это иметь абстрактный внутренний Builder класс внутри родительского. Затем он содержит защищенный конструктор для всех требуемых параметров, общих для дочерних классов, и некоторый javadoc, чтобы сообщить пользователю, что им необходимо реализовать свой собственный build() метод, который возвращает объект того же типа, что и возвращаемый класс. Это работает, если люди используют RTFM, в противном случае он ломается… что плохо. Любые идеи приветствуются.

примечание: Я застрял, работая в версии 1.4, поскольку это виртуальная машина выделенного оборудования, на котором она предназначена для запуска.

Комментарии:

1. Это будет сложно, поскольку в Java 1.4 у вас даже нет ковариантных возвращаемых типов

2. Мой совет был бы перестать пытаться быть слишком навороченным. Просто разработайте API для работы с конструктором и / или устаревшими установщиками. Это не так красиво, но, вероятно, в конечном итоге людям будет проще использовать. (Самое лучшее в том, чтобы биться головой о кирпичную стену, — это остановиться.)

3. @stephen Единственная проблема с использованием подхода группы конструкторов заключается в том, что существует большое количество необязательных параметров. Все становится довольно запутанным, когда вы предоставляете конструкторы для каждой возможной комбинации или выставляете объекты в недопустимых состояниях в случае установщиков, в противном случае я полностью согласен, что это было бы лучшим решением.

4. решение старой школы для множества необязательных параметров заключается в заполнении значений, отличных от значений по умолчанию, установщиками. Или использовать объект свойств или объект пользовательской конфигурации, если это параметры, которые повторно используются в нескольких вызовах конструктора.

5. Теперь я пошел по этому пути. Переработал пару вещей, чтобы уменьшить сложность, и добавил установщики, где это необходимо, наряду с некоторыми заводскими методами для создания объектов.

Ответ №1:

Один из способов «подделать» дженерики — заставить подкласс передать Class в конструктор.

 public class MySuperClass {

    private final Class clazz;

    protected MySuperClass(Class clazz) {
        this.clazz = clazz;
    }

    public void doSomethingGenericish(Object param) {
        // Pseudo generic check
        if (!param.getClass().isAssignableFrom(param)) {
            throw new ClassCastException("Could not cast "   param.getClass()   " as "   clazz);
        }
        // Some code
    }
}

public class MySubClass extends MySuperClass {

    protected MySubClass()
    {
        super(PseudoGenericsParameterClass.class);
    }
}
  

Комментарии:

1. Да, я подозреваю, что какая-то проверка во время выполнения будет лучшим, что вы можете сделать. В чем, собственно, и заключается весь смысл дженериков 🙂

2. К сожалению, это не позволит вам добавлять методы builder в подкласс и свободно комбинировать их вызовы с вызовами базового класса.

Ответ №2:

Дженерики — это просто удобство, которое позволяет компилятору принудительно использовать некоторые материалы для вас. Если вы просто тщательно документируете типы вещей и применяете эти правила самостоятельно, вы получите тот же результат без обобщений. Черт возьми, вы могли бы даже написать материал общего типа в комментариях и следовать им самостоятельно.

Комментарии:

1. Проблема с шаблоном builder заключается в том, что ваш build() метод должен возвращать объект того типа, который он создает. Хотя было бы возможно, чтобы build() метод просто возвращал объект, это зависело бы от правильного приведения его пользователем, что становится немного запутанным.