2016-11-29 4 views
1

Предположим, у меня есть абстрактный класс, Element и интерфейс Model.Общий шаблон и заводской шаблон

Element имеет способ setModel(Model model).

Say Element экземпляров ссылаются на один экземпляр Model реализации обычно, для таких вещей, как десериализации из ReST, сериализации кортежей SQL и т.д.

Каждых Element подкласса является ассоциированным с одним конкретным Model, но любой Model может быть связан с любое количество Element классов, так что-то вроде этого:

public abstract class Element<M extends Model> { 
    private M mModel; 
    public void setModel(M model) { 
    mModel = model; 
    } 
} 

И

public interface Model { 
    // .. stuff 
} 

Теперь предположим, что я хочу создать фабрику, которая производит элементы из моделей. Учитывая, что Модель может быть связана с несколькими классами Элементов, мы можем ожидать, что нам нужно предоставить конкретный класс. Так что-то вроде этого в конечном результате:

ElementSubclass e = new ElementFactory(ElementSubclass.class).from(someModelInstance); 

или ....

ElementFactory factory = new ElementFactory(ElementSubclass.class); 
for(Model model : listOfModels) { 
    ElementSubClass element = factory.from(model); 
    listOfElementSubClassInstances.add(element); 
} 

Getting там было менее очевидно, чем я бы подумал. Я в конечном итоге с чем-то вроде:

public class ElementFactory { 

    private Class<? extends Element> mElementClass; 

    public <E extends Element> ContentModelElementFactory(Class<E> elementClass) { 
    mElementClass = elementClass; 
    } 

    public <E extends Element> E from(Model model) { 
    try { 
     Element e = mElementClass.newInstance(); 
     e.setModel(model); 
     return (E) e; 
    } catch (Exception ex) { 
     // 
    } 
    return null; 
    } 

} 

Кажется немного шаткой, и ворсинки жалуется как призыв к setModel и гипсе на линии ниже.

Я считал что-то вроде new ElementFactory<ElementSubclass>(ElementSubclass.class), но это плохо читается - мы уже обозначили элементный подкласс один раз, кажется, что это тяжелый способ сделать это как тип, так и аргумент.

Существует также статическая версия, например public static <E extends Element> E create(Class<E> clazz, Model model), но, очевидно, она не может использоваться повторно как настоящая фабрика и кажется немного менее изящной.

Есть ли лучший способ выразить эту идею?

+0

Какова цель этого? Вы пытаетесь создать экземпляр и setModel в общем? Я что-то упускаю ? Кроме того, было бы хорошо, если бы вы добавили простой пример (например, Employee и т. Д.), Объясняющий конечную цель. – developer

+0

@ javaguy Основная цель - превратить модель в элемент по ссылке на класс. например, запрос базы данных или вызов rest возвращает модель, поэтому фабрика будет простым методом для создания элемента произвольного подкласса из этой модели. – momo

ответ

1

Поскольку общие типы стерты, вы должны передать свой ElementSubclass на заводе, никоим образом не обходитесь.

Если вы раздражены new ElementFactory<ElementSubclass>(ElementSubclass.class), тогда напишите общий статический метод, например public static <E extends Element> ElementFactory<E> of(Class<E> elementClass). Это даст вам код, как:

ElementFactory<ElementSubclass> factory = ElementFactory.of(ElementSubclass.class); 

Которая чувствует себя несколько лучше.

+0

Да, там я тоже закончил, или довольно близко (статический метод, на который ссылаются во втором-последнем абзаце). спасибо за подтверждение. – momo

Смежные вопросы