возможны ли иерархические версии в Java? - PullRequest
1 голос
/ 28 декабря 2010

Я играл с интересной идеей (не знаю, включу ли я ее в любой код, но об этом интересно думать)

Допустим, у нас есть программа, которая требует большого количества классов, все определенного подкласса. И все эти классы должны быть одиночками. Теперь мы могли бы написать шаблон синглтона для каждого из этих классов, но, кажется, расточительно писать один и тот же код снова и снова, и у нас уже есть общий базовый класс. Было бы неплохо создать метод getSingleton для A, который при вызове из подкласса возвращает единичный объект класса B (приведен к классу A для простоты)

class A{
     public A getSingleton(){
         //Wizardry
     }
}
class B extends A{
}

A blargh = B.getSingleton()
A gish = B.getSingleton()
if(A == B)
    System.out.println("It works!")

Мне кажется, что способ сделать это - распознать и вызвать конструктор B по умолчанию (при условии, что нам не нужно ничего передавать.) Я немного знаком с черной магией отражения в Java, но я Я не уверен, что это можно сделать.

Кто-нибудь заинтересован в том, чтобы ломать голову над этим?

Ответы [ 4 ]

2 голосов
/ 28 декабря 2010

Технически, я не вижу причин, по которым нечто подобное нельзя сделать. Ваша точная схема не будет работать, потому что ваш getSingleton равен static (даже если вы не можете объявить его как таковой), поэтому он не может определить, к какому классу он вызывается. Измените его на static A getSingleton(Class cls), и оно может быть работоспособным.

Тем не менее, действительно ли это большая часть выигрыша от наличия однострочного getSingleton в каждом производном классе?

Для начала ваш getSingleton возвращает A, поэтому, если кто-то вызывает его на B, он получает обратно A и вынужден понижать его, чтобы использовать его как B.

Кроме того, схема не совсем прозрачна.

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

2 голосов
/ 28 декабря 2010

Вы можете сделать это так, указав класс: (на самом деле вы можете использовать для всех классов, если у них есть конструктор public noargs)

//Code not tested
class A {
    private static ConcurrentHashMap<Class,Object> instances=new ConcurrentHashMap();

    private A(){}

    public static <T> T getInstance(Class<T extends A> classe) {
       Object instance=instances.get(classe);
       if(instance==null) {
         instance=createInstance(classe,instance);
       }
       return instance;
    }

    protected <T> T createInstance(Class<T> classe) {
      return classe.getConstructor().newInstance();
    }
}
1 голос
/ 31 декабря 2010

Это интересная идея.Другой способ уменьшить количество дублирующегося кода - использовать инструмент для обработки ваших «синглтонов».Обычный способ сделать это в Java - использовать инструмент для внедрения зависимостей, такой как Spring , который позволяет вам определять все типы, которые вы хотите использовать как одиночные, а затем запрашивать эти типы у Spring, когда вам нужноих.Spring тогда гарантирует, что он только когда-либо создает один из каждого запрашиваемого типа.Дублирование кода практически отсутствует.

Это имеет преимущество, заключающееся в том, чтобы не вызывать поведение Singleton для самого типа.Многие из проблем с Singletons связаны с тем, насколько невероятно сложно заставить его эффективно тестировать код из-за их глобального состояния (я был в проектах, где я провел много времени, помогая людям выяснить, как исправить неисправные тесты, потому чтодва разных теста модифицируют синглтон).Используя Spring, вы можете получить синглтоноподобное поведение, но также можете создавать отдельные экземпляры типов, когда это имеет смысл.

0 голосов
/ 28 декабря 2010

Ответ «нет», это невозможно.

Если наследование означает «IS-A», то B - это A, и они больше не являются синглетонами.

»... большое количество классов, все определенного подкласса. И все эти классы должны быть одиночными ... "

Я просто перечитал это.Разве «большое число» и «синглтон» не противоречат друг другу?

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

Google написал утилиты для идентификации синглетонов в их коде, чтобы их можно было удалить.Все еще хотите засорять ваш код ими?

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