Reputation: 1314
I've created a few classes as Controllers
for my routes in Node.js
and I'd like them to be able to work on a singleton basis (not required, it's an extra)
Main Controller class
class RouteController {
static getInstance() {
if (!RouteController.singleton) {
RouteController.singleton = new RouteController();
}
return RouteController.singleton;
}
}
Now I want to create a route for example viewing posts and I want that class to have the singleton pattern as well, but not cop
PostController class
class PostController extends RouteController {
}
If I do this and check it console.log(RouteController.getInstance() === PostController.getInstance())
it returns true
when I want each (sub)class to have their own singleton instance.
How can I do this correctly?
Upvotes: 0
Views: 45
Reputation: 816364
The normal rules of functions apply. Hence you can use this
inside the function to refer to the object the method was invoked on (the constructor function itself in this case):
class RouteController {
static getInstance() {
if (!this.singleton) {
this.singleton = new this();
}
return this.singleton;
}
}
However, this will still not work if RouteController.getInstance()
is called directly, because then all subclasses inherit a static singleton
property, causing the !this.singleton
test to fail for each subclass.
There are multiple ways to solve this. One would be to use getOwnProperty
instead of accessing it directly:
if (!this.getOwnProperty('singleton')) {
}
Upvotes: 0
Reputation: 32511
One simple way would be to see if your singleton
property is an instance of this
. This will work even if you call RouteController.getInstance()
before doing so on any of the derived classes.
class RouteController {
log() {
return 'Route';
}
static getInstance() {
if (!(this.singleton instanceof this)) {
// Only called twice so you can verify it's only initialized
// once for each class
console.log('Creating singleton...');
this.singleton = new this();
}
return this.singleton;
}
}
class PostController extends RouteController {
log() {
return 'Post';
}
}
console.log(RouteController.getInstance().log());
console.log(PostController.getInstance().log());
console.log(RouteController.getInstance().log());
console.log(PostController.getInstance().log());
Upvotes: 2