Singleton Factory - реализация с использованием Java 8 - PullRequest
0 голосов
/ 04 января 2019

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

У меня может быть универсальный тип возвращаемого значения в качестве объекта, но я не хочу приводить возвращаемый объект в каждом месте, которое я вызываюметод get instance.

Ниже приведен код: я получаю ошибку компиляции в строке c.cast (instance);

Мы не используем инъекцию Spring / зависимостей, но пытаемся реализоватьобщий класс для создания всех одноэлементных объектов.

Заранее спасибо.

public class SingletonFactory {
    public static Map<String,Object> objectFactory = new HashMap<String, Object>();

    public static <T extends Object> T getInstance(Class<?> c){
    String key = c.toString();
    Object instance= objectFactory.get(key);
    if(instance == null){
        synchronized (c) {
            try{
                instance = c.newInstance();
                objectFactory.put(key, instance);
            }catch(IllegalAccessException | InstantiationException e){
                throw new RuntimeException("Exception while creating singleton instance for class : "+key+" - Exception Message : "+e);
            }
        }
    }
    return c.cast(instance);
}

}

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Во-первых, вам нужно синхронизировать намного раньше, вы должны просто синхронизировать метод, в противном случае вы можете создать дополнительный экземпляр в состоянии гонки.

Во-вторых, вы должны определить родовой метод метода следующим образом:

public static <T> T getInstance(Class<? extends T> c)
0 голосов
/ 04 января 2019

Во-первых, я могу указать, что <T extends Object> можно заменить просто <T>, потому что все в Java, включая дженерики, должно быть объектом.

Вторая часть, с которой вы действительно близкиэто Class<?> c.Это говорит о том, что вы можете передать любой класс, и он вернет любой тип T.c.cast(instance) можно заменить на (T) instance, если вы считаете, что это выглядит лучше, но на самом деле есть разница, которая более детально описана здесь: Java Class.cast () и оператор приведения .

Окончательный код выглядит следующим образом:

public class SingletonFactory {
    public static Map<String,Object> objectFactory = new HashMap<String, Object>();

    public static <T> T getInstance(Class<T> c){
        String key = c.toString();
        Object instance= objectFactory.get(key);
        if(instance == null){
            synchronized (c) {
                try{
                    instance = c.newInstance();
                    objectFactory.put(key, instance);
                }catch(IllegalAccessException | InstantiationException e){
                    throw new RuntimeException("Exception while creating singleton instance for class : "+key+" - Exception Message : "+e);
                }
            }
        }
        return c.cast(instance);
        // or
        return (T) instance;
    }
}

Также, если вы действительно хотите, вы можете сохранить все в своем исходном коде и привести экземпляр к T в конце метода, и он должен работать,Единственное, что ваши вызовы методов будут выглядеть как SingletonFactory.getInstance<Foo>(Foo.class) вместо SingletonFactory.getInstance(Foo.class).Это из-за Class<?> в исходном коде вместо Class<T>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...