Шаблон Singleton: getInstance () против передачи объекта Singleton? - PullRequest
1 голос
/ 25 октября 2019

Какой правильный / самый популярный способ использовать шаблон Singleton.

  1. Ограничить номер. вызовов getInstance (), предпочтительно вызывать его только один раз и передавать объект другим классам во время их создания?
class SingletonClass {
// Implementataion
}

class MainClass {
    private SingletonClass singletonClassObject;

    public MainClass() {
        singletonClassObject = SingletonClass.getInstance();
        new SomeClass(singletonClassObject).doSomething();
        new SomeOtherClass(singletonClassObject).doSomethingElse();
    }
}

class SomeClass {
    private SingletonClass singletonClassObject;

    public SomeClass(SingletonClass singletonClassObject) {
        this.singletonClassObject = singletonClassObject;
    }

    public void doSomething() {
        System.out.println(singletonClassObject.getStuff());
    }
}

class SomeOtherClass {
    private SingletonClass singletonClassObject;

    public SomeOtherClass(SingletonClass singletonClassObject) {
        this.singletonClassObject = singletonClassObject;
    }

    public void doSomethingElse() {
        System.out.println(singletonClassObject.getStuff());
    }
}

Не передавайте одноэлементный объект. Скорее вызовите get ссылку на объект в каждом классе и сохраните ссылку как переменную экземпляра и используйте ее везде, где требуется.
class SingletonClass {
// Implementataion
}

class MainClass {
    public MainClass() {
        new SomeClass().doSomething();
        new SomeOtherClass().doSomethingElse();
    }
}

class SomeClass {
    private SingletonClass singletonClassObject;

    public SomeClass() {
        singletonClassObject = SingletonClass.getInstance();
    }

    public void doSomething() {
        System.out.println(singletonClassObject.getStuff());
    }
}

class SomeOtherClass {
    private SingletonClass singletonClassObject;

    public SomeOtherClass() {
        singletonClassObject = SingletonClass.getInstance();
    }

    public void doSomethingElse() {
        System.out.println(singletonClassObject.getStuff());
    }
}

Даже не сохраняйте ссылку как переменную экземпляра, а используйте SingletonClass.getInstance () везде, где вам нужен объект.
class SingletonClass {
// Implementataion
}

class MainClass {
    public MainClass() {
        new SomeClass().doSomething();
        new SomeOtherClass().doSomethingElse();
    }
}

class SomeClass {
    public SomeClass() {
    }

    public void doSomething() {
        System.out.println(SingletonClass.getInstance().getStuff());
    }
}

class SomeOtherClass {
    public SomeOtherClass() {
    }

    public void doSomethingElse() {
        System.out.println(SingletonClass.getInstance().getStuff());
    }
}

Как эти подходы лучше сравниваются друг с другомдизайн, тестируемость и т. д.? Что лучше и почему?

Ответы [ 2 ]

2 голосов
/ 27 октября 2019

Если на мгновение предположить, что SingletonClass не является синглтоном, и мы не получим экземпляр, вызвав метод static, мы столкнемся с другой проблемой, как связать эти классы вместе. Эта проблема решается с помощью Dependency Injection, и эта концепция хорошо описана здесь:

После прочтения выше должно быть легко выбрать параметр .1, где все классы попадают в конструктор со ссылками на требуемые зависимости. Вы даже можете создать interface для нужного вам поведения и реализовать его в SingletonClass. Теперь вы видите, что тот факт, что класс реализует шаблон Singleton , не делает его особенным, и мы должны внедрять их, как и другие классы. Все преимущества использования DI вы можете применить к своему классу.

Просто сравните его с .3, и вам нужно написать тест, в котором вам нужно что-то посмеяться. Это было бы более неприятной задачей, чем в случае .1.

0 голосов
/ 25 октября 2019

Посмотрите на это так: вы сомневаетесь в способности компилятора распознавать, что статическая конечная ссылка может быть скомпилирована как встроенная ссылка.

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

Я предполагаю, что getInstance () будет более эффективным.

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