В Java, Как реализовать функции, аналогичные использованию параметра шаблона, чтобы избежать создания подклассов Creator в C ++? - PullRequest
1 голос
/ 15 апреля 2019

Недавно, когда я читал книгу под названием «Элементы шаблона проектирования многоразового объектно-ориентированного программного обеспечения», в книге был такой параграф:

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

что я хочу знать: в Java, как реализовать функции, аналогичные использованию параметра шаблона, чтобы избежать создания подклассов Creator в C ++?

Я пытался использовать дженерики, но я не знаю, как их использовать.

public class ConcreteCreator<T extends Product> extends Creator{

    @Override
    public Product createProduct() {
        // ... how can I return new T();

    }
}

Ответы [ 3 ]

2 голосов
/ 15 апреля 2019

// ... как я могу вернуть новый T ();

Простой ответ: это не так просто в Java.

Java - это не C ++, и дженерики во многих отношениях менее мощны, чем шаблоны C ++.

Суть в том, что нет способа "генерировать" новые объекты какого-то неизвестного произвольного класса.Возможно, вы сможете обойти , используя рефлексию, и Class.forName() и newInstance(), но это происходит за счет обычных затрат на рефлексию: это неуклюже и подвержено ошибкам.

Конечно, вы можете вернуть определенный тип подкласса (и экземпляр там), но тогда вам нужно написать конкретный метод для каждого такого типа.

1 голос
/ 15 апреля 2019

В Java уже есть универсальный тип для фабричных методов.Это Supplier<T>.

Вы, вероятно, должны использовать Supplier<Product> вместо вашего Creator.

Затем вы обычно используете лямбда-функцию или ссылку на метод для предоставления экземпляра.

Если вы хотите вызвать, например, setCreator(Supplier<Product>), и вы хотите, чтобы он создал ваш подкласс MyProduct, то просто позвоните setCreator(MyProduct::new).

Lambdas, позволяющие выполнять более сложные конструкции безсоздание подклассов, даже когда соответствующий конструктор не существует, например setCreator(() -> new MyProduct(CONST_VAL_1, UtilityClass.getCurrentValue2());

1 голос
/ 15 апреля 2019

Вы не можете создать экземпляр T.Это заполнитель, который будет удален во время выполнения.Вместо возврата Product вы хотите вернуть конкретный тип Product.

...