JavaScript, SOLID, and factories

Mark Stephenson
5 min readFeb 22, 2021

Firstly i’ll acknowledge the elephant in the room:

“Javascript cant do solid”

I’m not going to get into that particular debate other than to say whether or not you agree with whether or not you can or cant follow these principals I personally believe there are codebases where coding with these in mind can help keep things clean.

This article is written as a result of an innocuous enough looking component that I was modifying.

The component that was being modified was the ‘container’ component. The part which has the header containing a title, and a ‘body’ area. Initially, the task was to modify the component so that we could pass a clickable button to it that would be displayed on the right of the header section.

This was easy enough to implement. End of story.

Not quite as it turns out.

Just like most of our applications our code and components are subject to change over time as a result of new feature requirements. Here I needed to allow the passing of a collection of ‘icons with behaviours’. I have changed the definition somewhat as one of the behaviours actually requires a component that consists of an input and label which launches a file upload dialog.

Now, I have two types of component that, selectively, need to be rendered based on a type.

Solution 1

There is likely to only be these two types of components that would ever be rendered. So, a simple switch or ternary would solve the problem.

Q: As we quickly found out in the intro, things change. What happens if there is a third, or fourth requirement?

A: I end up having to modify the logic and add another case to my selective rendering. This could quickly get out of hand and by introducing the switch in the first place we break the first window of our house… which invites others to do the same (If you dont know what im blathering about here I recommend reading Clean Code by Bob Martin).

Solution 2

The second solution would be to extract the mapping into a factory function. The factory pattern is super useful, but a lot of implementations I see end up using a switch which just moves the problem.

I was forwarded the 👆 above article by a colleague and it superbly outlines the problem space (better than I could) and offers a factory solution that doesnt use a switch (which violates the Open Closed principal).

In honesty, for my small use case either solution 1 or 2 would be fine, but because I started looking I also felt that the approach outlined in the linked article is obviously much neater, but doesn’t really solve the Open/Closed issue. It moves it into a FactoryMapper method. Its neat, and clean, but I wanted to see how else we could handle this.

Solution 3

Our front end is Javascript, but our API is PHP. In PHP we code to an interface where possible. An interface would allow me the flexibility and safety I was wanting. The problem is that Javascript doesnt have interfaces. 😠

The snippet shows a simplified version of what I want to achieve.

Given a collection of different types of buttons render them. To the list of mixedButtons I should be able to pass ANY type of button and have it render.

In order to safely render anything passed to it we need to ensure our buttons conform to this simple contract. It must have a render method. I know that Typescript can provide us with interfaces, but I think that we should use those in conjunction with something that can throw errors rather than produce a red squiggly line in our IDE.

If you are not the kind of developer that likes throwing packages at problems then you could roll your own. I started to create a naive implementation which I will probably expand to include type checking and walking of the proto tree, but likely just as an exercise to better understand things.

Using this function you can check to see if one class implements the methods and static methods of another. This is the foundations of an interface, and good enough for my example.

Now, my two button classes can be defined, but I can check to see that both classes implement a render method (and more).

What’s more, if want to add one, two or any number of new types of buttons to be rendered I can create the classes, make sure they conform to the interface requirements and safely pass them into my iterator for rendering without having to modify the file at all.

Extra

There is a really cool library called implement-js which I will be looking at that provides seems to provide the functionality I am looking for.

I highly recommend checking out the linked Medium article whether you are not familiar with the factory pattern, or if you have only ever implemented it using switches.

--

--