Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

Using Static Class Methods To Generate Concrete Instances Of Abstract Classes In JavaScript And Node.js

By Ben Nadel on

The other day, I was building a JavaScript class that depended on another Abstract class as an injected value. The Abstract class only exposed one abstract method that needed to be overridden in a sub-class. I know that not everyone - especially in the Node.js community - is so hot on writing Classes; so, I wanted to see if I could provide a workflow that could consume just the concrete method without having to define an entire sub-class. To do this, I created a static factory function on the abstract class that merged the concrete method into the abstract instance.

JavaScript is enchantingly dynamic (and that's before you even get to ES6 Proxy objects). You can create objects from Prototypes; you can manually construct objects by weaving properties together; or, you can do a little of this and a little of that. And, it's this last approach that I am using in my static factory function. Rather than defining a sub-class, I'm just instantiating the abstract class (because "Abstract" isn't a formal part of the JavaScript language); and then, I'm manually injecting the concrete methods into the abstract instance, thereby "completing" it:

class AbstractThing {

	// ---
	// ---

	doThis() {
		throw( new Error( "Abstract method." ) );

	doThat() {
		throw( new Error( "Abstract method." ) );

	// ---
	// ---

	execute() {

	// ---
	// ---

	// I provide a way to create a concrete implementation of the AbstractThing class
	// by providing the concrete functions. This is in lieu of creating a base class that
	// extends the AbstractThing class explicitly.
	static usingFunctions({ doThis, doThat }) {

		var implementation = new AbstractThing();

		// Override the abstract methods with the given concrete functions.
		implementation.doThis = doThis;
		implementation.doThat = doThat;

		return( implementation );



// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //

// Create a concrete instance using the two concrete methods (no base class needed).
var thing = AbstractThing.usingFunctions({
	doThis: function() {
		console.log( "... do this." );
	doThat: function() {
		console.log( "... do that." );

console.log( "Is instance of AbstractThing:", ( thing instanceof AbstractThing ) );

As you can see, the AbstractThing class requires two methods to be overridden in its sub-classes: doThis() and doThat(). The static method, usingFunctions(), takes these two required methods, instantiates the AbstractThing class and then, manually overrides the abstract methods with the given concrete ones.

When we run this code though Node.js, we get the following terminal output:

Using static methods to generate concrete instances of abstract classes in JavaScript.

Works like a charm. There's no magic here, really. This is just JavaScript being JavaScript, which is why JavaScript is so awesome. Of course, this approach only works if there's no additional constructor logic needed by the concrete class. But, if you only need to provide one or two functions (which can be powered by lexical scoping rather than constructor arguments), this seems like a fun little pattern to use.

Reader Comments