Kirk Ouimet
Kirk Ouimet

Reputation: 28364

Have parent class use child class in static method in Node JS?

Let's say I have these two subclasses:

Male.js

var Person = require('./Person.js');

class Male extends Person {
    ...
}

module.exports = Male;

Female.js

var Person = require('./Person.js');

class Female extends Person {
    ...
}

module.exports = Female;

And finally I have this base class:

Person.js

class Person {

    static makePersonBySettings(settings) {
        var person;

        if(settings.gender == 'male') {
            person = new Male(settings.name);
        }
        else if(settings.gender == 'female') {
            person = new Female(settings.name);
        }

        return person;
    }

}

module.exports = Person;

Parent's static method depends on knowing what the Male and Female classes are. I can't do require('./Male.js'); at the top of Person.js because Male depends on Person.

Objective-C, Java, and more allow you to do this as the issue is resolved by the compiler.

What's the best way to resolve this issue with Node JS?

Upvotes: 3

Views: 543

Answers (2)

McMath
McMath

Reputation: 7188

If I understand correctly, makePersonBySettings() is a function that allows the user to create a Male of Female instance without direct access to those classes. And I think you want to have Male, Female, and Person in separate files. This is a bit of an unusual pattern in Node. However, if you want to follow this pattern, you can do this:

Define your Person class, but leave out makePersonBySettings() for now.

// person-base.js
'use strict';

class Person { ... }

module.exports = Person;

Define your Male and Female classes; require Person at the top of each.

// female.js
'use strict';

var Person = require('./person-base');

class Female extends Person { ... }

module.exports = Female;

In a separate file, require your Male, Female, and Person files, and now add your static method, like so:

// person.js
'use strict';

var Person = require('./person-base');
var Male = require('./male');
var Female = require('./female');

Person.makePersonBySettings = function() {
  // You can reference Male and Female here.
};

module.exports = Person;

And now you can require('./person.js') whenever you need it.

I think, though, you would do better to consider the factory pattern mentioned by @TudorConstantin, unless that is completely off the table for some reason.

Upvotes: 0

Tudor Constantin
Tudor Constantin

Reputation: 26861

It's probably best to use the Factory pattern, like this:

function Maternity{
    this.giveBirthTo = function(settings){
        var person;
        if(settings.gender == 'male') {
            person = new Male(settings.name);
        }
        else if(settings.gender == 'female') {
            person = new Female(settings.name);
        }

        return person;
    }
}

then, later in code:

var factory = new Maternity();
var john = factory.giveBirthTo({name: 'John', gender:'male'});

Upvotes: 3

Related Questions