Должен ли я передать синглтон в качестве параметра функции - PullRequest
0 голосов
/ 06 февраля 2019

Я недавно столкнулся в обзоре кода, который я делал с коллегой, по странной схеме, которую я раньше не видел.Он отправлял синглтон в качестве параметра функции и сохранял его в вызывающем классе как член.Допустим, у меня есть простой синглтон-класс Foo

public class Foo {

private static Foo instance;
private int counter;

private Foo(){}

public static Foo getInstance(){
    if (instance == null){
        instance = new Foo();
    }
    return instance;
}

public int getCounter() {
    return counter;
}

public void setCounter(int counter) {
    this.counter = counter;
}
}

Теперь есть клиент Foo с именем Bar:

public class Bar {

private Foo foo;

public Bar(Foo foo){
    this.foo = foo;
    this.foo.setCounter(10);
    this.foo.setCounter(20);
}

public int getCounter(){
    return foo.getCounter();
}
}

Так что Bar делает 2 необычные вещи- 1. Вызовите Foo в конструкторе, вместо использования Foo.getInstance() и 2. Сохраните Foo в качестве члена, чтобы «сохранить» шаблон вызова Foo.getInstance(), он использует его.Конечно, примеры, которые я продемонстрировал, тривиальны.

Это выглядело странно и неловко для меня, и, что еще хуже, я не могу определить Foo как синглтон вообще в Bar области видимости.Что если я поменяю что-то важное в этом состоянии?Но, кроме этой причины читабельности кода, я не могу сказать, что это не является обязательным, и использование кажется в конечном итоге допустимым.Был ли я прав или нет?и по какой причине?Правильно ли передать этот синглтон и сохранить его как участника?

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Не принято, но я думаю, что в соответствии с использованием: 1) Передача синглтона в качестве параметра конструктору другого класса может быть допустимой.2) хранение экземпляра синглтона от клиента также может быть допустимым.
МОК может сделать это, например.

Теперь это может быть нежелательно, если вы хотите добавить к getInstance() некоторую логику: кэширование экземпляров, возвращение различных экземпляров в соответствии с временной шкалой, клиентом и т. Д. Но это действительно хороший способ реализациисинглтон с таким большим количеством логики?Не уверен ...

Это выглядело странно и неловко для меня, и, что еще хуже, я вообще не могу идентифицировать Фу как синглтона в области видимости Бар.

Нообразец синглтона также неуклюж.Если одноэлементный шаблон предоставляет ссылку на экземпляр одноэлементного доступа клиентам, он может использовать его бесплатно.

Почему вы думаете, что, когда вы смотрите на штрих-код, вы должны знать, что Foo является одиночным?
Бар зависит от Foo, потому что он в этом нуждается.Реализация (синглтон или нет) не должна иметь значения на своем уровне.

В общем случае следует избегать «жестко закодированного» одноэлементного шаблона: своего рода глобальной переменной, труднее переключаться на другие реализации, труднее издеваться ...
Если бы вы могли использовать перечисление Java 5это не должно быть сложно реализовать с вашим реальным кодом, это было бы действительно лучше.

Дополнительное примечание для фактического синглтона:

Не является поточно-ориентированным.Использование идиомы Билла Пью сделает это легко.

public class Foo {

    private static class Holder{
       private static Foo instance = new Foo();
    }

    private Foo(){}

    public static Foo getInstance(){
        return Holder.instance();
    }
}

Это ленивый экземпляр, как в вашем исходном коде.
Но в общем случае очень важно сэкономить экземпляр, который стоит недорого иобязателен.
Стремительный путь так часто предпочитается:

public class Foo {

    private static Foo instance = new Foo();

    private Foo(){}

    public static Foo getInstance(){
        return instance;
    }
}
0 голосов
/ 06 февраля 2019

Кажется, это действительно субъективно.Сохранение ссылки на синглтон может оказаться полезным, если вы считаете, что существует вероятность того, что код в какой-то момент может больше не быть синглтоном, или если вы думаете, что можете перейти к среде, такой как Spring, с внедрением зависимостей.Таким образом, вы можете сказать, что с нетерпением ждем будущей гибкости.В общем, синглтоны не одобряются как противоречащие действительно объектно-ориентированному коду.

Но в то же время, если ваше приложение сильно зависит от синглтонов, и это очень типичный шаблон ... и если вы 'если вы обеспокоены тем, что каким-то образом вы можете получить дублирующиеся экземпляры класса singleton из-за этого использования, то можно утверждать, что этот код не соответствует общему шаблону вашего приложения и ожидаемому использованию и должен соответствовать ожидаемым рекомендациям.

Не зная больше о вашем заявлении, команде и т. Д., Трудно дать более конкретный ответ, чем этот.

...