Итак, во-первых, здесь есть неправильное представление:
Я пытался удалить super, чтобы не получить экземпляр, но затем я получил ошибку
super()
вызывает родительский класс ' конструктор в созданном экземпляре дочернего класса (то есть, на что ссылается this
). Он не возвращает экземпляр родительского класса. См. Здесь для получения дополнительной информации.
Таким образом, вызов super()
совсем не нарушает свойство singleton родительского класса. Он может быть построен только один раз, если реализован правильно.
Имея это в виду, вам следует немного улучшить свой код.
Разумным изменением будет удаление управления экземплярами из конструкторов. Одним из решений будет использование статических конструкторов , которые либо создают синглтон, если экземпляр не существует, либо возвращают созданный экземпляр.
Еще один способ - передать аргументы конструкторам синглтон-классов. На самом деле не имеет смысла передавать аргументы классу, который должен быть создан один раз (вы никогда не будете снова ничего делать с аргументами конструктора). Вы можете просто сделать аргументы свойствами синглтона сразу. Вот SO ответ , поддерживающий этот пункт для синглетонов Java.
Полный пример со статическими конструкторами и без аргументов выглядит следующим образом:
let instanceA = null;
let instanceB = null;
let counters = { A: 0, B: 0 }; // count class instantiations
class A {
static getInstance() {
if (instanceA === null) {
instanceA = new A();
}
return instanceA;
}
whoami() {
const name = this.constructor.name;
return `${name} #${counters[name]}`;
}
constructor() {
counters[this.constructor.name] += 1;
}
}
class B extends A {
static getInstance() {
if (instanceB === null) {
instanceB = new B();
}
return instanceB;
}
constructor() {
super();
}
}
const a1 = A.getInstance();
const a2 = A.getInstance();
const a3 = A.getInstance();
const b1 = B.getInstance();
const b2 = B.getInstance();
const b3 = B.getInstance();
console.log(a1.whoami());
console.log(a2.whoami());
console.log(a3.whoami());
console.log(b1.whoami());
console.log(b2.whoami());
console.log(b3.whoami());
Обратите внимание, что B
наследует whoami
от A
и что счетчики вызовов конструктора никогда не увеличиваются после 1.
Очевидно, что при таком подходе вы не можете гарантировать, что свойство singleton сохраняется для каждого класса, если только статические конструкторы не используются для генерации экземпляров (поскольку конструкторы все еще доступны). Я думаю, что это хороший компромисс.