2014-12-10 4 views
1

Я сегодня убираю часть своего кода, в котором участвуют несколько классов фабрик для создания разных классов «на лету» с пользовательского ввода. Я нашел все, что они следуют почти одинаковую картину:java factory methods and generics

public class MyClassFactory{ 
    private static MyClassFactory singleton = new MyClassFactory(); 
    public static MyClassFactory getInstance(){return singleton;} 
    private MyClassFactory(); 
    private HashMap<String, Class<? extends MyClass>> instances = new HashMap<>(); 

    public void register(String name, Class<? extends MyClass> clazz){ 
     instances.put(name, clazz); 
    } 

    public MyClass getByName(String name) throw ...{ 
     return instances.get(name).newInstance(); 
    } 
} 

Мой вопрос заключается в следующем, я не должен быть в состоянии сделать супер класс для этого, где я могу пройти в типе класса, как общий. Что-то вроде этого:

public class SimpleFactory T<Class>{ 
    private HashMap<String, Class<T>> instances = new HashMap<>(); 

    public void register(String name, Class<? extends T> clazz){ 
     instances.put(name, clazz); 
    } 
    //or possibly public <T> T getByName.... 
    public T getByName(String name) throw ...{ 
     return instances.get(name).newInstance(); 
    } 
} 

public class MyClassFactory extends SimpleFactory<MyClass.class>{ 
    private static MyClassFactory singleton = new MyClassFactory(); 
    public static MyClassFactory getInstance(){return singleton;} 
    private MyClassFactory(); 
} 

К сожалению, я получаю ошибки компиляции на всем MyClassFactory класса это, кажется, результатом MyClass.class и насыщает «неверное число аргументов, требуется 1».

Возможно ли это/стоит?

ответ

2

Во-первых, у вас есть опечатка на первой строке вашего объявления класса SimpleFactory. Я думаю, что вы ищете что-то вроде

public class SimpleFactory<T> { 

И тогда подкласс будет

public class MyClassFactory extends SimpleFactory<MyClass> { 

Рассмотрим сделать базовый класс абстрактным.

В любом случае, если ваше приложение сильно зависит от синглтонов и имеет какую-либо сложность или будет продолжать расти по сложности, присмотритесь к использованию контейнера IOC, такого как Spring или Guice. Я лично большой поклонник весной. Есть те, кто жалуется на его сложность, но он входит в модули, и вам не нужно все использовать. Мои два цента.

+0

Хорошее место на опечатка - я над думая, я думал, что я должен был пройти в типе класса в качестве общего , Отличная работа. –

+0

спасибо, Zack. – RichW

0

У вас здесь очень неправильный синтаксис. Я не 100% уверен, что вы после этого, но следующие прекрасно работает:

public class SimpleFactory<T> { 
    private HashMap<String, Class<? extends T>> instances = new HashMap<>(); 

    public void register(String name, Class<? extends T> clazz){ 
     instances.put(name, clazz); 
    } 
    //or possibly public <T> T getByName.... 
    public T getByName(String name) throws ... { 
     return instances.get(name).newInstance(); 
    } 
} 

public class MyClassFactory extends SimpleFactory<MyClass> { ... }