2013-04-01 2 views
2

У меня естьJava шаблон завод, использующий общие ограничения

public class MyFactory() 
{ 
    public static <T> T getItem(Element element, Class<T> clazz) 
    { 
     T item = null; 
     if (clazz == IFoo.class) 
     { 
       item = (T) new Foo(); 
     } 
     else if (clazz == IBar.class) 
     { 
       item = (T) new Bar(); 
     } 
     ... 

     assert item instanceof IParsable; 
     (IParsable(foo)).parse(element) 

     return item; 
    } 

} 

, а затем я его называю, как этот

IFoo parsedFoo = MyFactory.getItem(someElement, IFoo.class); 

Здесь конкретные классы реализуют IParsable. Смогу ли я удалить проверку проверки выполнения во время выполнения и поставить проверку времени компиляции, чтобы увидеть, будет ли «IParsable» и «разбор вызова»?

Также мне было интересно, если есть способ обеспечить IFoo < -> Foo реализует отношения во время компиляции в getItem() методы и удалить типажи (T)?

EDIT: Я думал, что я дал бы наброски IFoo и Foo

public interface IFoo 
{ 
    String getFooName(); 
    int getFooId(); 
    .... 
} 


class Foo implements IFoo, IParsable 
{ 
     ... 
} 

EDIT2:

Я просто подумал, что рефакторинга, как это, теперь единственное, что не проверяется во время компиляции является связь между интерфейсом и реализацией.

public static <U extends IParsable, T> T getItem(Element element, Class<T> clazz) 
    { 
     U item = null; 
     if (clazz == IFoo.class) 
     { 
       item = (U) new Foo(); 
     } 
     else if (clazz == IBar.class) 
     { 
       item = (U) new Bar(); 
     } 
     ... 

     item.parse(element) 

     return (T) item; 
    } 

ответ

3

Может быть что-то вроде этого:

public static <T> T getItem(Element element, Class<T> clazz) { 
    IParsable item = null; 
    if (clazz == IFoo.class) { 
     item = new Foo(); 
    } else if (clazz == IBar.class) { 
     item = new Bar(); 
    } 
    item.parse(); 
    return (T) item; 
} 

Тот факт, что Foo является IParsable проверяется во время компиляции. Другой литой (до (T)) по-прежнему является упражнением во время выполнения, но это также было в вашем примере.

+0

На самом деле, это никогда не проверяет, что Foo можно использовать для IFoo, так как общий ролик, подобный этому, удаляется во время выполнения. – jtahlborn

+2

Вы хотите, чтобы 'return clazz.cast (item);'. – jtahlborn

+0

@jtahlborn Да, действительно. – assylias

1

Здесь конкретные классы реализуют IParsable. Смогу ли я удалить проверку проверки выполнения во время выполнения и поставить проверку времени компиляции, чтобы увидеть, будет ли «IParsable» и «разбор вызова»?

From what I know - no, it's not possible. You will be passing object to this method at runtime, the compiler has no idea what objects will be passed. So compile time is not an option here. 

Также был интересен, если есть способ для обеспечения IFoo < -> Foo реализует отношений во время компиляции в GetItem метода() и удалить типажи (T)?

Again, only at runtime with isAssignableFrom 
1

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

private static Map<Class<?>, Class<?>> MAPPINGS = ...; 

static { 
    registerMapping(IFoo.class, Foo.class, Foo.class); 
    // ... 
} 

private static <IT, TT extends IT, TP extends IParseable> void registerMapping(Class<IT> ifaceClazz, Class<TT> implClazz, TP parseableClazz) { 
    MAPPINGS.put(ifaceClazz, implClazz); 
} 

затем в getItem() ваш, если блок витки в простой поиск по карте. Обратите внимание: это не избавит вас от броска (T), но вы ничего не можете с этим поделать.

+1

Это сработает, но это еще не проверка времени компиляции. – assylias

+0

@assylias - вы правы. – jtahlborn

+0

@assylias - обновил мой ответ. – jtahlborn

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